home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / unix / volume4 / se / part4 < prev    next >
Encoding:
Internet Message Format  |  1986-11-30  |  56.5 KB

  1. From: Jeff Lee <talcott!seismo!gatech!jeff>
  2. Subject: Georgia Tech 'se' screen editor (Part 4 of 8)
  3. Keywords: Software Tools, Yet Another Screen Editor, Both BSD and USG
  4. Newsgroups: mod.sources
  5. Approved: jpn@panda.UUCP
  6.  
  7. Mod.sources:  Volume 4, Issue 85
  8. Submitted by: Jeff Lee <seismo!gatech!jeff>
  9.  
  10. #! /bin/sh
  11. # This is a shell archive, meaning:
  12. # 1. Remove everything above the #! /bin/sh line.
  13. # 2. Save the resulting text in a file.
  14. # 3. Execute the file with /bin/sh (not csh) to create:
  15. #    screen.c
  16. #    scriptse.c
  17. #    term.c
  18. # This archive created: Tue Apr 29 11:02:14 1986
  19. export PATH; PATH=/bin:/usr/bin:$PATH
  20. echo shar: "extracting 'screen.c'" '(22973 characters)'
  21. if test -f 'screen.c'
  22. then
  23.     echo shar: "will not over-write existing file 'screen.c'"
  24. else
  25. cat << \SHAR_EOF > 'screen.c'
  26. /*
  27. ** screen.c
  28. **
  29. ** screen handling functions for the screen editor.
  30. */
  31.  
  32.  
  33. #include "se.h"
  34. #include "extern.h"
  35. #include <time.h>
  36.  
  37. /* clrrow --- clear out all of a row except the bar */
  38.  
  39. clrrow (row)
  40. register int row;
  41. {
  42.     loadstr ("", row, 0, BARCOL - 1);
  43.     loadstr ("", row, BARCOL + 1, Ncols - 1);
  44. }
  45.  
  46.  
  47.  
  48. /* display_message --- copy contents of message file to screen */
  49.  
  50. display_message (fp)
  51. FILE *fp;
  52. {
  53.     char lin[MAXCOLS];
  54.     char *fgets ();
  55.     int row, col, eof, k;
  56.     static char more[] = " M O R E   T O   C O M E ";
  57.  
  58.     if (Toprow > 0)
  59.     {
  60.         Topln = max (0, Topln - (Toprow - 1));
  61.         Toprow = 0;
  62.     }
  63.  
  64.     eof = NO;
  65.     for (row = Toprow; row <= Botrow; row++)
  66.     {
  67.         if (fgets (lin, Ncols, fp) == NULL)
  68.         {
  69.             eof = YES;
  70.             break;
  71.         }
  72.         Toprow++;
  73.         Topln++;
  74.         lin[strlen (lin)] = EOS;        /* remove '\n' */
  75.         loadstr (lin, row, 0, Ncols);
  76.     }
  77.  
  78.     if (eof == NO)
  79.     {
  80.         k = (Ncols - strlen (more)) / 2;
  81.         for (col = 0; col < k; col++)
  82.             load ('*', row, col);
  83.  
  84.         for (k = 0; more[k] != EOS; k++, col++)
  85.             load (more[k], row, col);
  86.  
  87.         for (; col < Ncols; col++)
  88.             load ('*', row, col);
  89.  
  90.         Toprow++;
  91.         Topln++;
  92.         row++;
  93.     }
  94.  
  95.     for (col = 0; col < Ncols; col++)
  96.         load ('-', row, col);
  97.     Toprow++;
  98.     Topln++;
  99.  
  100.     if (Topln > Lastln)
  101.         adjust_window (0, Lastln);
  102.  
  103.     if (Curln < Topln)
  104.         Curln = Topln;
  105.  
  106.     First_affected = Topln;        /* must rewrite the whole screen */
  107.  
  108.     mesg ("Enter o- to restore display", HELP_MSG);
  109.  
  110.     if (eof == YES)
  111.         return (EOF);
  112.  
  113.     return (OK);
  114. }
  115.  
  116. static char smargin[] = "MARGIN";
  117.  
  118. /* getcmd --- read a line from the terminal (for se) */
  119.  
  120. getcmd (lin, col1, curpos, termchar)
  121. char *lin, *termchar;
  122. int col1, *curpos;
  123. {
  124.     int cursor, nlpos, prev_cursor, prev_status, status,
  125.     scan_pos, tab_pos, first, strlen (),
  126.     scan_tab (), scan_char (), cread ();
  127.     char c;
  128.  
  129.     nlpos = strlen (lin) - 1;
  130.     if (nlpos == -1 || lin[nlpos] != '\n')
  131.         nlpos++;
  132.  
  133.     if (*curpos < 0)
  134.         cursor = 0;
  135.     else if (*curpos >= MAXLINE - 1)
  136.         cursor = nlpos;
  137.     else
  138.         set_cursor (*curpos, &status, &cursor, &nlpos, lin);
  139.     prev_cursor = cursor;
  140.  
  141.     watch ();    /* display the time of day */
  142.  
  143.     switch (Nchoise) {    /* update the line number display */
  144.     case CURLINE:
  145.         litnnum ("line ", Curln, LINE_MSG);
  146.         break;
  147.     case LASTLINE:
  148.         litnnum ("$ = ", Lastln, LINE_MSG);
  149.         break;
  150.     case TOPLINE:
  151.         litnnum ("# = ", Topln, LINE_MSG);
  152.         break;
  153.     default:
  154.         mesg ("", LINE_MSG);
  155.         break;
  156.     }
  157.  
  158.     if (cursor + 1 < Warncol)    /* erase the column display */
  159.         mesg ("", COL_MSG);
  160.  
  161.     *termchar = EOS;    /* not yet terminated */
  162.     status = OK;
  163.     prev_status = ERR;
  164.     first = col1;
  165.  
  166.     while (*termchar == EOS)
  167.     {
  168.         lin[nlpos] = EOS;    /* make sure the line has an EOS */
  169.         if (status == ERR)    /* last iteration generated an error */
  170.             twrite (1, "\007", 1);    /* Bell */
  171.         else if (prev_status == ERR)    /* last one OK but one before had error */
  172.             mesg ("", CHAR_MSG);
  173.  
  174.         prev_status = status;
  175.         status = OK;
  176.  
  177.         if (first > cursor)     /* do horiz. scroll if needed */
  178.             first = cursor;
  179.         else if (first < cursor - Ncols + POOPCOL + 1)
  180.             first = cursor - Ncols + POOPCOL + 1;
  181.  
  182.         if (first == col1)      /* indicate horizontally shifted line */
  183.             load ('|', Cmdrow, BARCOL);
  184.         else if (first > col1)
  185.             load ('<', Cmdrow, BARCOL);
  186.         else if (first < col1)
  187.             load ('>', Cmdrow, BARCOL);
  188.         loadstr (&lin[first], Cmdrow, POOPCOL, Ncols - 1);
  189.  
  190.         if (cursor == Warncol - 1 && prev_cursor < Warncol - 1)
  191.             twrite (1, "\007", 1);   /* Bell */
  192.         if (cursor >= Warncol - 1)
  193.             litnnum ("col ", cursor + 1, COL_MSG);
  194.         else if (prev_cursor >= Warncol - 1)
  195.             mesg ("", COL_MSG);
  196.  
  197.         position_cursor (Cmdrow, cursor + POOPCOL - first);
  198.         prev_cursor = cursor;
  199.  
  200.         /* get a character  */
  201.         switch (c = cread()) {        /* branch on character value */
  202.  
  203.     /* Literal characters: */
  204.         case ' ': case '!': case '"': case '#': case '$': case '%': 
  205.         case '&': case '\'': case '(': case ')': case '*': case '+':
  206.         case ',': case '-': case '.': case '/': case '0': case '1': 
  207.         case '2': case '3': case '4': case '5': case '6': case '7':
  208.         case '8': case '9': case ':': case ';': case '<': case '=': 
  209.         case '>': case '?': case '@': case '[': case '\\': case ']':
  210.         case '^': case '_': case '`': case '{': case '|': case '}': 
  211.         case '~': case 'A': case 'B': case 'C': case 'D': case 'E':
  212.         case 'F': case 'G': case 'H': case 'I': case 'J': case 'K': 
  213.         case 'L': case 'M': case 'N': case 'O': case 'P': case 'Q':
  214.         case 'R': case 'S': case 'T': case 'U': case 'V': case 'W': 
  215.         case 'X': case 'Y': case 'Z': case 'a': case 'b': case 'c':
  216.         case 'd': case 'e': case 'f': case 'g': case 'h': case 'i': 
  217.         case 'j': case 'k': case 'l': case 'm': case 'n': case 'o':
  218.         case 'p': case 'q': case 'r': case 's': case 't': case 'u': 
  219.         case 'v': case 'w': case 'x': case 'y': case 'z': case ESC:
  220.             if (c == ESC) /* take next char literally */
  221.             {
  222.                 if ((c = cread()) == '\r')
  223.                     c = '\n';
  224.             }
  225.             else if (Invert_case == YES && isalpha (c))
  226.                 c ^= 040;       /* toggle case (ASCII only) */
  227.             if (Insert_mode == YES)
  228.                 insert (1, &nlpos, &status, cursor, lin);
  229.             else if (cursor >= MAXLINE - 2)
  230.             {
  231.                 status = ERR;
  232.                 mesg (smargin, CHAR_MSG);
  233.             }
  234.             if (status != ERR)
  235.             {
  236.                 lin[cursor++] = c;
  237.                 if (nlpos < cursor)
  238.                     nlpos = cursor;
  239.                 if (c == '\n')
  240.                     *termchar = CURSOR_SAME;
  241.             }
  242.             break;
  243.  
  244.     /* Leftward cursor functions: */
  245.         case CURSOR_LEFT:
  246.             set_cursor (cursor - 1, &status, &cursor, &nlpos, lin);
  247.             break;
  248.  
  249.         case TAB_LEFT:
  250.             tab_pos = scan_tab (TAB_LEFT, cursor, &status);
  251.             if (status != ERR)
  252.                 cursor = tab_pos;
  253.             break;
  254.  
  255.         case SKIP_LEFT:
  256.             cursor = 0;
  257.             break;
  258.  
  259.         case SCAN_LEFT:
  260.             scan_pos = scan_char (c, YES, cursor, nlpos,
  261.                 lin, &status);
  262.             if (status != ERR)
  263.                 cursor = scan_pos;
  264.             break;
  265.  
  266.         case G_LEFT:
  267.             set_cursor (cursor - 1, &status, &cursor, &nlpos, lin);
  268.             if (status != ERR)
  269.                 gobble (1, cursor, &status, &nlpos, lin);
  270.             break;
  271.  
  272.         case G_TAB_LEFT:
  273.             tab_pos = scan_tab (TAB_LEFT, cursor, &status);
  274.             if (status != ERR)
  275.             {
  276.                 cursor = tab_pos;
  277.                 gobble (prev_cursor - tab_pos, cursor,
  278.                     &status, &nlpos, lin);
  279.             }
  280.             break;
  281.  
  282.         case KILL_LEFT:
  283.             cursor = 0;
  284.             gobble (prev_cursor /* - 1 */, cursor, &status, &nlpos, lin);
  285.             break;
  286.  
  287.         case G_SCAN_LEFT:
  288.             scan_pos = scan_char (c, NO, cursor, nlpos,
  289.                 lin, &status);
  290.             if (status != ERR)
  291.             {
  292.                 cursor = scan_pos;
  293.                 gobble (prev_cursor - scan_pos, cursor,
  294.                     &status, &nlpos, lin);
  295.             }
  296.             break;
  297.  
  298.     /* Rightward cursor functions: */
  299.         case CURSOR_RIGHT:
  300.             set_cursor (cursor + 1, &status, &cursor, &nlpos, lin);
  301.             break;
  302.  
  303.         case TAB_RIGHT:
  304.             tab_pos = scan_tab (TAB_RIGHT, cursor, &status);
  305.             if (status != ERR)
  306.                 set_cursor (tab_pos, &status, &cursor,
  307.                     &nlpos, lin);
  308.             break;
  309.  
  310.         case SKIP_RIGHT:
  311.             cursor = nlpos;
  312.             first = col1;
  313.             break;
  314.  
  315.         case SCAN_RIGHT:
  316.             scan_pos = scan_char (c, YES, cursor, nlpos,
  317.                 lin, &status);
  318.             if (status != ERR)
  319.                 cursor = scan_pos;
  320.             break;
  321.  
  322.         case G_RIGHT:
  323.             gobble (1, cursor, &status, &nlpos, lin);
  324.             break;
  325.  
  326.         case G_TAB_RIGHT:
  327.             tab_pos = scan_tab (TAB_RIGHT, cursor,
  328.                 &status);
  329.             if (status != ERR)
  330.                 gobble (tab_pos - cursor, cursor, &status,
  331.                     &nlpos, lin);
  332.             break;
  333.  
  334.         case KILL_RIGHT:
  335.             gobble (nlpos - cursor, cursor, &status, &nlpos, lin);
  336.             break;
  337.  
  338.         case G_SCAN_RIGHT:
  339.             scan_pos = scan_char (c, NO, cursor, nlpos,
  340.                 lin, &status);
  341.             if (status != ERR)
  342.                 gobble (scan_pos - cursor, cursor, &status,
  343.                     &nlpos, lin);
  344.             break;
  345.  
  346.     /* Line termination functions: */
  347.         case T_SKIP_RIGHT:
  348.             cursor = nlpos;
  349.             *termchar = c;
  350.             break;
  351.  
  352.         case T_KILL_RIGHT:
  353.             nlpos = cursor;
  354.             *termchar = c;
  355.             break;
  356.  
  357.         case FUNNY:
  358.         case CURSOR_UP:
  359.         case CURSOR_DOWN:
  360.             *termchar = c;
  361.             break;
  362.  
  363.     /* Insertion functions: */
  364.         case INSERT_BLANK:
  365.             insert (1, &nlpos, &status, cursor, lin);
  366.             if (status != ERR)
  367.                 lin[cursor] = ' ';
  368.             break;
  369.  
  370.         case INSERT_NEWLINE:
  371.             insert (1, &nlpos, &status, cursor, lin);
  372.             if (status != ERR)
  373.             {
  374.                 lin[cursor] = '\n';
  375.                 *termchar = CURSOR_UP;
  376.             }
  377.             break;
  378.  
  379.         case INSERT_TAB:
  380.             while (lin[cursor] == ' ' || lin[cursor] == '\t')
  381.                 cursor++;
  382.             tab_pos = scan_tab (TAB_RIGHT, cursor, &status);
  383.             if (status != ERR)
  384.                 insert (tab_pos - cursor, &nlpos, &status,
  385.                     cursor, lin);
  386.             if (status != ERR)
  387.                 for (; cursor < tab_pos; cursor++)
  388.                     lin[cursor] = ' ';
  389.             cursor = prev_cursor;
  390.             break;
  391.  
  392.     /* Miscellanious control functions: */
  393.         case TOGGLE_INSERT_MODE:
  394.             Insert_mode = YES + NO - Insert_mode;
  395.             if (Insert_mode == NO)
  396.                 mesg ("", INS_MSG);
  397.             else
  398.                 mesg ("INSERT", INS_MSG);
  399.             break;
  400.  
  401.         case SHIFT_CASE:
  402.             Invert_case = YES + NO - Invert_case;
  403.             if (Invert_case == NO)
  404.                 mesg ("", CASE_MSG);
  405.             else
  406.                 mesg ("CASE", CASE_MSG);
  407.             break;
  408.  
  409.         case KILL_ALL:
  410.             nlpos = cursor = 0;
  411.             break;
  412.  
  413.         case FIX_SCREEN:
  414.             restore_screen ();
  415.             break;
  416.  
  417.         default:
  418.             status = ERR;
  419.             mesg ("WHA?", CHAR_MSG);
  420.             break;
  421.         } /* end switch */
  422.     } /* while (termchar == EOS) */
  423.  
  424.     lin[nlpos] = '\n';
  425.     lin[nlpos + 1] = EOS;
  426.  
  427.     load ('|', Cmdrow, BARCOL);
  428.     if (nlpos <= col1)
  429.         loadstr ("", Cmdrow, POOPCOL, Ncols - 1);
  430.     else
  431.         loadstr (&lin[col1], Cmdrow, POOPCOL, Ncols - 1);
  432.  
  433.     if (cursor >= Warncol - 1)
  434.         litnnum ("col ", cursor + 1, COL_MSG);
  435.     else if (prev_cursor >= Warncol - 1)
  436.         mesg ("", COL_MSG);
  437.  
  438.     *curpos = cursor;
  439. }
  440.  
  441.  
  442.  
  443. /* cread --- read a character, handle interrupts and hangups */
  444. /*              ALL keyboard input should pass through this routine */
  445.  
  446. int cread ()
  447. {
  448.     char c;
  449.     int read ();
  450.  
  451.     tflush ();
  452.     if (Peekc)
  453.     {
  454.         c = Peekc;
  455.         Peekc = EOS;
  456.     }
  457.     else
  458.     {
  459. #ifdef BSD4_2
  460.         Reading = YES;
  461. #endif
  462.         if (read (0, &c, 1) == -1)
  463.             if (Hup_caught)
  464.                 hangup ();
  465.             else    /* must be a SIGINT at present */
  466.             {
  467.                 Int_caught = 0;
  468.                 Errcode = ENOERR;
  469.                 c = '\177';
  470.             }
  471. #ifdef BSD4_2
  472.         Reading = NO;
  473. #endif
  474.     }
  475.  
  476.     return c;
  477. }
  478.  
  479.  
  480.  
  481. /* scan_char --- scan current line for a character */
  482.  
  483. static int scan_char (chr, wrap, cursor, nlpos, lin, status)
  484. char chr, *lin;
  485. int wrap, cursor, nlpos, *status;
  486. {
  487.     register char c;
  488.     register int inc, scan_pos;
  489.     int cread ();
  490.  
  491.     c = cread ();
  492.     if (Invert_case == YES && isalpha (c))
  493.         c ^= 040;       /* toggle case */
  494.     if (c == chr)
  495.         c = Last_char_scanned;
  496.     Last_char_scanned = c;
  497.  
  498.     if (chr == SCAN_LEFT || chr == G_SCAN_LEFT)
  499.         inc = -1;
  500.     else
  501.         inc = 1;
  502.  
  503.     /* NOTE:  modify this code AT YOUR OWN RISK! */
  504.     scan_pos = cursor;
  505.     do
  506.     {
  507.         if (scan_pos < 0)
  508.             if (wrap == NO)
  509.                 break;
  510.             else
  511.                 scan_pos = nlpos;
  512.         else if (scan_pos > nlpos)
  513.             if (wrap == NO)
  514.                 break;
  515.             else
  516.                 scan_pos = 0;
  517.         else
  518.             scan_pos += inc;
  519.         if (-1 < scan_pos && scan_pos < nlpos && lin[scan_pos] == c)
  520.             break;
  521.     } while (scan_pos != cursor);
  522.  
  523.     if (scan_pos < 0 || scan_pos >= nlpos || lin[scan_pos] != c)
  524.     {
  525.         *status = ERR;
  526.         mesg ("NOCHAR", CHAR_MSG);
  527.     }
  528.  
  529.     return (scan_pos);
  530. }
  531.  
  532.  
  533.  
  534. static int scan_tab (chr, cursor, status)
  535. char chr;
  536. int cursor, *status;
  537. {
  538.     register int inc, tab_pos;
  539.  
  540.     if (chr == TAB_LEFT)
  541.     {
  542.         inc = -1;
  543.         tab_pos = cursor - 1;
  544.     }
  545.     else
  546.     {
  547.         inc = 1;
  548.         tab_pos = cursor + 1;
  549.     }
  550.  
  551.     for (; -1 < tab_pos && tab_pos < MAXLINE; tab_pos += inc)
  552.         if (Tabstops[tab_pos] == YES)
  553.             break;
  554.  
  555.     if (tab_pos < 0 || tab_pos >= MAXLINE - 1)
  556.     {
  557.         *status = ERR;
  558.         mesg (smargin, CHAR_MSG);
  559.     }
  560.  
  561.     return (tab_pos);
  562. }
  563.  
  564.  
  565.  
  566. /* gobble --- delete characters starting at the current cursor position */
  567.  
  568. static gobble (len, cursor, status, nlpos, lin)
  569. int len, cursor, *status, *nlpos;
  570. char *lin;
  571. {
  572.     if (cursor + len > *nlpos)
  573.     {
  574.         *status = ERR;
  575.         mesg (smargin, CHAR_MSG);
  576.     }
  577.     else if (len > 0)
  578.     {
  579.         strcpy (&lin[cursor], &lin[cursor + len]);
  580.         *nlpos -= len;
  581.     }
  582. }
  583.  
  584.  
  585.  
  586. /* insert --- shift characters right starting at the current cursor position */
  587.  
  588. static insert (len, nlpos, status, cursor, lin)
  589. register int len, *nlpos, cursor;
  590. int *status;
  591. register char *lin;
  592. {
  593.     register int fr, to;
  594.  
  595.     if (*nlpos + len >= MAXLINE - 1)
  596.     {
  597.         *status = ERR;
  598.         mesg (smargin, CHAR_MSG);
  599.     }
  600.     else
  601.     {
  602.         for (fr = *nlpos, to = *nlpos + len; fr >= cursor; fr--, to--)
  603.             lin[to] = lin[fr];
  604.         *nlpos += len;
  605.     }
  606. }
  607.  
  608.  
  609.  
  610. /* set_cursor --- move the cursor, extend line if necessary */
  611.  
  612. static set_cursor (pos, status, cursor, nlpos, lin)
  613. register int pos, *status, *cursor, *nlpos;
  614. register char *lin;
  615. {
  616.     if (pos < 0 || pos >= MAXLINE - 1)
  617.     {
  618.         *status = ERR;
  619.         mesg (smargin, CHAR_MSG);
  620.     }
  621.     else
  622.     {
  623.         *cursor = pos;
  624.         for (; *nlpos < *cursor; (*nlpos)++)
  625.             lin[*nlpos] = ' ';
  626.     }
  627. }
  628.  
  629.  
  630. /* litnnum --- display literal and number in message area */
  631.  
  632. litnnum (lit, num, type)
  633. register char *lit;
  634. register int num, type;
  635. {
  636.     char msg[MAXLINE];
  637.  
  638.     sprintf (msg, "%s%d", lit, num);
  639.     mesg (msg, type);
  640. }
  641.  
  642.  
  643.  
  644. /* load --- load a character onto the screen at given coordinates */
  645.  
  646. load (chr, row, col)
  647. register char chr;
  648. register int row, col;
  649. {
  650.     register char ch;
  651.  
  652.     ch = (chr < ' ' || chr >= DEL) ? Unprintable : chr;
  653.  
  654.     if (row >= 0 && row < Nrows && col >= 0 && col < Ncols
  655.         && Screen_image[row][col] != ch)
  656.     {
  657.         position_cursor (row, col);
  658.         Screen_image[row][col] = ch;
  659.         send (ch);
  660.     }
  661. }
  662.  
  663.  
  664. /* loadstr --- load a string into a field of the screen */
  665.  
  666. loadstr (str, row, stcol, endcol)
  667. register char *str;
  668. int row, stcol, endcol;
  669. {
  670.     register char ch;
  671.     register int p, c, limit;
  672.  
  673.     if (row >= 0 && row < Nrows && stcol >= 0)
  674.     {
  675.         c = stcol;
  676.         for (p = 0; str[p] != EOS; p++)
  677.         {
  678.             if (c >= Ncols)
  679.                 break;
  680.             ch = str[p];
  681.             if (ch < ' ' || ch >= DEL)
  682.                 ch = Unprintable;
  683.             if (Screen_image[row][c] != ch)
  684.             {
  685.                 Screen_image[row][c] = ch;
  686.                 position_cursor (row, c);
  687.                 send (ch);
  688.             }
  689.             c++;
  690.         }
  691.         if (endcol >= Ncols - 1 && c < Ncols - 1)
  692.             clear_to_eol (row, c);
  693.         else
  694.         {
  695.             limit = (endcol < Ncols - 1) ? endcol : Ncols - 1;
  696.             for (; c <= limit; c++)
  697.                 if (Screen_image[row][c] != ' ')
  698.                 {
  699.                     Screen_image[row][c] = ' ';
  700.                     position_cursor (row, c);
  701.                     send (' ');
  702.                 }
  703.         }
  704.     }
  705. }
  706.  
  707.  
  708. /* mesg --- display a message in the status row */
  709.  
  710. mesg (s, t)
  711. char *s;
  712. register int t;
  713. {
  714.     register int col, need, c, first, last;
  715.     int strlen ();
  716.  
  717.     for (first = 0; first < Ncols; first++)
  718.         if (Msgalloc[first] == t)
  719.             break;
  720.     for (last = first; last < Ncols; last++)
  721.     {
  722.         if (Msgalloc[last] != t)
  723.             break;
  724.         Msgalloc[last] = NOMSG;
  725.     }
  726.     for (; first > 0 && Msgalloc[first - 1] == NOMSG; first--)
  727.         ;
  728.  
  729.     need = strlen (s) + 2;  /* for two blanks */
  730.  
  731.     if (need > 2)           /* non-empty message */
  732.     {
  733.         if (need <= last - first)       /* fits in previous slot */
  734.             col = first;        /* keep it there */
  735.         else        /* needs a new slot */
  736.             for (col = 0; col < Ncols - 1; col = c)
  737.             {
  738.                 while (col < Ncols - 1
  739.                     && Msgalloc[col] != NOMSG)
  740.                     col++;
  741.                 for (c = col; Msgalloc[c] == NOMSG; c++)
  742.                     if (c >= Ncols - 1)
  743.                         break;
  744.                 if (c - col >= need)
  745.                     break;
  746.             }
  747.  
  748.         if (col + need >= Ncols)        /* have to collect garbage */
  749.         {
  750.             col = 0;
  751.             for (c = 0; c < Ncols; c++)
  752.                 if (Msgalloc[c] != NOMSG)
  753.                 {
  754.                     load (Screen_image[Nrows - 1][c],
  755.                         Nrows - 1, col);
  756.                     Msgalloc[col] = Msgalloc[c];
  757.                     col++;
  758.                 }
  759.             for (c = col; c < Ncols; c++)
  760.                 Msgalloc[c] = NOMSG;
  761.         }
  762.  
  763.         load (' ', Nrows - 1, col);
  764.         loadstr (s, Nrows - 1, col + 1, 0);
  765.         load (' ', Nrows - 1, col + need - 1);
  766.         last = col + need - 1;
  767.         if (last > Ncols - 1)
  768.             last = Ncols - 1;
  769.         for (c = col; c <= last; c++)
  770.             Msgalloc[c] = t;
  771.     }
  772.  
  773.     for (col = 0; col < Ncols; col++)
  774.         if (Msgalloc[col] == NOMSG)
  775.             load ('.', Nrows - 1, col);
  776.     tflush ();
  777. }
  778.  
  779. /* prompt --- load str into margin of command line */
  780.  
  781. prompt (str)
  782. char *str;
  783. {
  784.     loadstr (str, Cmdrow, 0, BARCOL - 1);
  785.     tflush ();
  786. }
  787.  
  788.  
  789.  
  790. /* restore_screen --- screen has been garbaged; fix it */
  791.  
  792. restore_screen ()
  793. {
  794.     register int row, col;
  795.     int intrpt ();
  796.  
  797.     clrscreen ();
  798.     for (row = 0; row < Nrows && ! intrpt (); row++)
  799.         for (col = 0; col < Ncols; col++)
  800.             if (Screen_image[row][col] != ' ')
  801.             {
  802.                 position_cursor (row, col);
  803.                 send (Screen_image[row][col]);
  804.             }
  805.  
  806.     remark ("");    /* get rid of 'type control-q....' */
  807. }
  808.  
  809. /* saynum --- display a number in the message area */
  810.  
  811. saynum (n)
  812. int n;
  813. {
  814.     char s[MAXLINE];
  815.  
  816.     sprintf (s, "%d", n);
  817.     remark (s);
  818. }
  819.  
  820. /* updscreen --- update screen from edit buffer */
  821.  
  822. updscreen ()
  823. {
  824.     char abs_lineno[10], rel_lineno[10];
  825.     register int line, row;
  826.     register int i;
  827.     int prevln ();
  828.     register LINEDESC *k;
  829.     LINEDESC *getind ();
  830.  
  831.     fixscreen ();
  832.  
  833.     line = Topln;
  834.     k = getind (line);
  835.  
  836.     for (row = Toprow; row <= Botrow; row++)
  837.     {
  838.         if (line > Lastln || line < 1)
  839.         {
  840.             loadstr ("", row, 0, BARCOL - 1);
  841.             load ('|', row, BARCOL);
  842.             loadstr ("", row, BARCOL + 1, Ncols - 1);
  843.         }
  844.         else
  845.         {
  846.             if (line == Curln)
  847.                 loadstr (".  ->", row, 0, NAMECOL - 1);
  848.             else if (line == 1)
  849.                 loadstr ("1", row, 0, NAMECOL - 1);
  850.             else if (line == Lastln)
  851.                 loadstr ("$", row, 0, NAMECOL - 1);
  852.             else if (Absnos == NO && row <= 25)
  853.             {
  854.                 rel_lineno[0] = Rel_a + row;
  855.                 rel_lineno[1] = EOS;
  856.                 loadstr (rel_lineno, row, 0, NAMECOL - 1);
  857.             }
  858.             else
  859.             {
  860.                 sprintf (abs_lineno, "%d", line);
  861.                 loadstr (abs_lineno, row, 0, NAMECOL - 1);
  862.             }
  863.  
  864.             load ((char) k->Markname, row, NAMECOL);
  865.             load ('|', row, BARCOL);
  866.  
  867.             if (line >= First_affected)
  868.             {
  869.                 gtxt (k);
  870.                 if (Firstcol >= k->Lineleng)
  871.                     loadstr ("", row, POOPCOL, Ncols - 1);
  872.                 else
  873.                     loadstr (&Txt[Firstcol], row, POOPCOL,
  874.                         Ncols - 1);
  875.             }
  876.         }
  877.  
  878.         line++;
  879.         k = NEXTLINE(k);
  880.     }
  881.  
  882.     First_affected = Lastln;
  883.  
  884.     Sctop = Topln;
  885.     Sclen = Botrow - Toprow + 1;
  886.     for (i = 0; i < Sclen; i++)
  887.         Scline[i] = Sctop + i <= Lastln ? i : -1;
  888. }
  889.  
  890.  
  891.  
  892. /* warn_deleted --- indicate which rows on screen are no longer valid */
  893.  
  894. warn_deleted (from, to)
  895. register int from, to;
  896. {
  897.     register int row;
  898.  
  899.     for (row = Toprow; row <= Botrow; row++)
  900.         if (Topln + row - Toprow >= from
  901.             && Topln + row - Toprow <= to)
  902.             loadstr ("gone", row, 0, BARCOL - 1);
  903. }
  904.  
  905.  
  906. /* watch --- keep time displayed on screen for users without watches */
  907.  
  908. watch ()
  909. {
  910.     long clock;
  911.     struct tm *now, *localtime ();
  912.     char face[10];
  913.  
  914.     time (&clock);
  915.     now = localtime (&clock);
  916.     sprintf (face, "%02d:%02d", now->tm_hour, now->tm_min);
  917.     mesg (face, TIME_MSG);
  918. }
  919.  
  920. /* adjust_window --- position window to include lines 'from' through 'to' */
  921.  
  922. adjust_window (from, to)
  923. register int from, to;
  924. {
  925.     register int i, l1, l2, hw;
  926.     int hwinsdel();
  927.  
  928.     /* see if the whole range of lines is on the screen */
  929.     if (from < Topln || to > Topln + (Botrow - Toprow))
  930.     {
  931.         /* find the first and last lines that are on the screen */
  932.         for (i = 0; i < Sclen && Scline[i] == -1; i++)
  933.             ;
  934.         l1 = i < Sclen ? Scline[i] + Sctop : Lastln + 1;
  935.         for (i = Sclen - 1; i >= 0 && Scline[i] == -1; i--)
  936.             ;
  937.         l2 = i >= 0 ? Scline[i] + Sctop : 0;
  938.  
  939.         /* see if we have hardware line insert/delete */
  940.         hw = hwinsdel();
  941.  
  942.         /* now find the best place to move the screen */
  943.         if (to - from > Botrow - Toprow)
  944.             Topln = to - (Botrow - Toprow);     /* put last part on screen */
  945.         else if (hw && from >= l1 && to <= l2)
  946.             Topln = (l1 + l2 + Toprow - Botrow) / 2;/* center l1 through l2 */
  947.         else if (hw && from < l1 && l1 - from < (Botrow - Toprow + 1) / 2)
  948.             Topln = from;                       /* slide the screen down */
  949.         else if (hw && to > l2 && to - l2 < (Botrow - Toprow + 1) / 2)
  950.             Topln = to - (Botrow - Toprow);     /* slide the screen up */
  951.         else
  952.             Topln = (from + to + Toprow - Botrow) / 2; /* center the range */
  953.         if (Topln + (Botrow - Toprow) > Lastln)
  954.             Topln = Lastln - (Botrow - Toprow);
  955.         if (Topln < 1)
  956.             Topln = 1;
  957.         if (First_affected > Topln)
  958.             First_affected = Topln;
  959.     }
  960. }
  961.  
  962.  
  963. /* svdel --- record the deletion of buffer lines for screen update */
  964.  
  965. svdel (ln, n)
  966. register int ln, n;
  967. {
  968.     register int i, j, lb, ub;
  969.  
  970.     if (ln + n <= Sctop)
  971.         Sctop -= n;
  972.     else if (ln < Sctop)
  973.     {
  974.         ub = ln + n - Sctop;
  975.         for (i = 0; i < Sclen; i++)
  976.             if (Scline[i] == -1)
  977.                 ;
  978.             else if (Scline[i] < ub)
  979.                 Scline[i] = -1;
  980.             else
  981.                 Scline[i] -= ub;
  982.         Sctop = ln;
  983.     }
  984.     else
  985.     {
  986.         lb = ln - Sctop;
  987.         ub = ln + n - Sctop;
  988.         for (i = 0; i < Sclen; i++)
  989.             if (Scline[i] == -1 || Scline[i] < lb)
  990.                 ;
  991.             else if (Scline[i] < ub)
  992.                 Scline[i] = -1;
  993.             else
  994.                 Scline[i] -= n;
  995.     }
  996. }
  997.  
  998.  
  999. /* svins --- record a buffer insertion for screen updating */
  1000.  
  1001. svins (ln, n)
  1002. register int ln, n;
  1003. {
  1004.     register int i, lb;
  1005.  
  1006.     if (ln < Sctop)
  1007.         Sctop += n;
  1008.     else
  1009.     {
  1010.         lb = ln - Sctop;
  1011.         for (i = 0; i < Sclen; i++)
  1012.             if (Scline[i] != -1 && Scline[i] > lb)
  1013.                 Scline[i] += n;
  1014.     }
  1015.  
  1016. }
  1017.  
  1018.  
  1019. /* fixscreen --- try to patch up the screen using insert/delete line */
  1020.  
  1021. fixscreen ()
  1022. {
  1023.     register int oi;    /* "old" screen index */
  1024.     register int ni;    /* "new" screen index */
  1025.     register int dc;    /* number of deletions in current block */
  1026.     register int ic;    /* number of insertions in current block */
  1027.     register int ul;    /* number of lines that must be rewritten if */
  1028.                 /* we don't update by insert/delete */
  1029.     int wline[MAXROWS];    /* new screen contents; Scline contains old */
  1030.     int p;
  1031.  
  1032.     /* if the screen width was changed, give up before it's too late */
  1033.     if (Botrow - Toprow + 1 != Sclen || ! hwinsdel())
  1034.         return;
  1035.  
  1036.     /* scale the offsets in Scline to the new Topln; set any that are */
  1037.     /* off the screen to -1 so we won't have to fool with them */
  1038.     for (oi = 0; oi < Sclen; oi++)
  1039.         if (Scline[oi] == -1 || Scline[oi] + Sctop < Topln
  1040.             || Scline[oi] + Sctop > Topln + (Botrow - Toprow))
  1041.             Scline[oi] = -1;
  1042.         else
  1043.             Scline[oi] += Sctop - Topln;
  1044.  
  1045.     /* fill in wline with only those numbers that are in Scline */
  1046.     for (oi = 0, ni = 0; ni < Sclen; ni++)
  1047.     {
  1048.         while (oi < Sclen && Scline[oi] == -1)
  1049.             oi++;
  1050.         if (oi < Sclen && Scline[oi] == ni)
  1051.         {
  1052.             wline[ni] = ni;
  1053.             oi++;
  1054.         }
  1055.         else
  1056.             wline[ni] = -1;
  1057.     }
  1058.  
  1059.     /* see if it's still advisable to fix the screen: if the number */
  1060.     /* of lines that must be rewritten is less than 2 + the number */
  1061.     /* of lines that must be inserted, don't bother (this is a dumb */
  1062.     /* but fairly effective heuristic) */
  1063.     ul = ni = 0;
  1064.     for (oi = 0; oi < Sclen; oi++)
  1065.     {
  1066.         if (Scline[oi] != wline[oi] || Scline[oi] == -1)
  1067.             ul++;
  1068.         if (wline[oi] == -1)
  1069.             ni++;
  1070.     }
  1071.     if (ul < ni + 2)
  1072.         return;
  1073.  
  1074.     /* Now scan the screens backwards and put out delete-lines */
  1075.     /* for all deletions and changes with more old lines than new */
  1076.     oi = ni = Sclen - 1;
  1077.     while (oi >= 0 || ni >= 0)
  1078.     {
  1079.         for (dc = 0; oi >= 0 && Scline[oi] == -1; dc++)
  1080.             oi--;
  1081.         for (ic = 0; ni >= 0 && wline[ni] == -1; ic++)
  1082.             ni--;
  1083.         if (dc > ic)
  1084.             dellines (oi + 1 + Toprow + ic, dc - ic);
  1085.         while (oi >= 0 && Scline[oi] != -1
  1086.             && ni >= 0 && wline[ni] == Scline[oi])
  1087.             oi--, ni--;
  1088.     }
  1089.  
  1090.     /* At last, scan the screens forward and put out insert-lines */
  1091.     /* for all insertions and changes with more new lines than old */
  1092.     oi = ni = 0;
  1093.     while (oi < Sclen || ni < Sclen)
  1094.     {
  1095.         p = ni;
  1096.         for (dc = 0; oi < Sclen && Scline[oi] == -1; dc++)
  1097.             oi++;
  1098.         for (ic = 0; ni < Sclen && wline[ni] == -1; ic++)
  1099.             ni++;
  1100.         if (ic > dc)
  1101.             inslines (p + Toprow + dc, ic - dc);
  1102.         while (oi < Sclen && Scline[oi] != -1
  1103.             && ni < Sclen && wline[ni] == Scline[oi])
  1104.             oi++, ni++;
  1105.     }
  1106.  
  1107. }
  1108.  
  1109.  
  1110. #ifdef HARD_TERMS
  1111. /* senddelay --- send NULs to delay n milliseconds */
  1112.  
  1113. senddelay (n)
  1114. int n;
  1115. {
  1116.     register int q;
  1117.  
  1118.     q = (long) n * Tspeed / 1000l;
  1119.     while (q > 0)
  1120.     {
  1121.         twrite (1, "\0\0\0\0\0\0\0\0\0\0", q > 10 ? 10 : q);
  1122.         q -= 10;
  1123.     }
  1124. }
  1125. #endif
  1126. SHAR_EOF
  1127. fi
  1128. echo shar: "extracting 'scriptse.c'" '(619 characters)'
  1129. if test -f 'scriptse.c'
  1130. then
  1131.     echo shar: "will not over-write existing file 'scriptse.c'"
  1132. else
  1133. cat << \SHAR_EOF > 'scriptse.c'
  1134. /*
  1135. ** scriptse.c
  1136. **
  1137. ** turn input into a form se
  1138. ** can use as a script.
  1139. **
  1140. ** This is very quick-and-dirty, not checking
  1141. ** for any of se's control characters.
  1142. */
  1143.  
  1144. #include <stdio.h>
  1145.  
  1146. main (argc, argv)
  1147. int argc;
  1148. char **argv;
  1149. {
  1150.     register int c;
  1151.     register int dflag = 0;
  1152.  
  1153.     if (argc > 1)
  1154.         if (strcmp (argv[1], "-d") == 0)
  1155.             dflag = 1;
  1156.         else
  1157.         {
  1158.             fprintf (stderr, "usage: %s [-d] < file > newfile\n",
  1159.                 argv[0]);
  1160.             exit (1);
  1161.         }
  1162.  
  1163.     while ((c = getchar()) != EOF)
  1164.     {
  1165.         if (c != '\n')        /* most frequent case */
  1166.             putchar (c);
  1167.         else
  1168.         {
  1169.             putchar ('\r');
  1170.             if (! dflag)
  1171.                 putchar ('\177');
  1172.         }
  1173.     }
  1174.     
  1175.     exit (0);
  1176. }
  1177. SHAR_EOF
  1178. fi
  1179. echo shar: "extracting 'term.c'" '(33039 characters)'
  1180. if test -f 'term.c'
  1181. then
  1182.     echo shar: "will not over-write existing file 'term.c'"
  1183. else
  1184. cat << \SHAR_EOF > 'term.c'
  1185. /*
  1186. ** term.c
  1187. **
  1188. ** provide terminal functions for se
  1189. **
  1190. ** If HARD_TERMS is *not* defined, which is the default, se will
  1191. ** use the termlib library, which provides terminal independant operations.
  1192. ** This makes se both smaller, and more flexible.
  1193. **
  1194. ** If HARD_TERMS is defined, then se will use the original code, which
  1195. ** had terminal types hard-wired into the code.  This would be useful for
  1196. ** a system which does not have the termlib library.
  1197. **
  1198. ** On System V systems, we have two possibilities.  Release 1 did not have
  1199. ** the terminfo package, so we assume that if it is Release 1, someone will
  1200. ** have ported the BSD termlib library.  If it is Release 2, then the new
  1201. ** terminfo package is there, and we wil use it.
  1202. */
  1203.  
  1204. #include "se.h"
  1205. #include "extern.h"
  1206.  
  1207. #ifndef HARD_TERMS
  1208.  
  1209. int outc ();    /* defined later */
  1210.  
  1211. #if defined (BSD) || !defined (S5R2)
  1212. /*
  1213.  * code for using BSD termlib -- getting capabilities, and writing them out.
  1214.  */
  1215.  
  1216. /* capabilities from termcap */
  1217.  
  1218. static int AM;        /* automatic margins, i.e. wraps at column 80 */
  1219.  
  1220. static char *VS;    /* visual start -- e.g. clear status line */
  1221. static char *VE;    /* visual end -- e.g. restore status line */
  1222. static char *TI;    /* terminal init -- whatever needed for screen ops */
  1223. static char *TE;    /* terminal ops end */
  1224. static char *CM;    /* cursor motion, used by tgoto() */
  1225. static char *CE;    /* clear to end of line */
  1226. static char *DL;    /* hardware delete line */
  1227. static char *AL;    /* hardware add (insert) line */
  1228. static char *CL;    /* clear screen */
  1229.  
  1230. extern char PC;        /* Pad character, usually '\0' */
  1231.  
  1232. static char *pcstr;
  1233. extern char *tgoto (), *tgetstr ();    /* termlib routines */
  1234.  
  1235. static char caps[128];        /* space for decoded capability strings */
  1236. static char *addr_caps;        /* address of caps for relocation */
  1237.  
  1238. #define TERMBUFSIZ    1024+1
  1239. static char termbuf[TERMBUFSIZ];
  1240.  
  1241.  
  1242.  
  1243. /* setterm -- initialize terminal parameters and actual capabilities */
  1244.  
  1245. static setterm (type)
  1246. char *type; 
  1247. {
  1248.     if (type[0] == EOS)
  1249.     {
  1250.         ttynormal ();
  1251.         fprintf (stderr, "in setterm: can't happen.\n");
  1252.         exit (1);
  1253.     }
  1254.  
  1255.     Ncols = Nrows = 0;
  1256.  
  1257.     /*
  1258.      * we used to set certain mininum and maximum screen sizes,
  1259.      * but since we could end up on things like ATT 5620s, with big
  1260.      * screens, we just do it dynamically, but add some error
  1261.      * checking, and exit if can't do it.
  1262.      */
  1263.     Nrows = tgetnum ("li");
  1264.     Ncols = tgetnum ("co");
  1265.  
  1266.     if (Nrows == -1)
  1267.     {
  1268.         ttynormal ();
  1269.         fprintf (stderr, "se: could not determine number of rows\n");
  1270.         exit (1);
  1271.     }
  1272.  
  1273.     if (Ncols == -1)
  1274.     {
  1275.         ttynormal ();
  1276.         fprintf (stderr, "se: could not determine number of columns\n");
  1277.         exit (1);
  1278.     }
  1279.  
  1280.     
  1281.     addr_caps = caps;
  1282.  
  1283.     getdescrip ();            /* get terminal description */
  1284.  
  1285.     if (*tgoto (CM, 0, 0) == 'O')    /* OOPS returned.. */
  1286.         CM = 0;
  1287.  
  1288.     PC = pcstr ? pcstr[0] : EOS;
  1289.  
  1290.     if (CM == 0)
  1291.     {
  1292.         ttynormal ();
  1293.         fprintf (stderr, "se: terminal does not have cursor motion.\n");
  1294.         exit (2);
  1295.     }
  1296.  
  1297.     return OK;
  1298. }
  1299.  
  1300. /* getdescrip --- get descriptions out of termcap entry */
  1301.  
  1302. static getdescrip ()
  1303. {
  1304.     int i;
  1305.     static struct _table {
  1306.         char *name;
  1307.         char **ptr_to_cap;
  1308.         } table[] = {
  1309.             "vs",    & VS,
  1310.             "ve",    & VE,
  1311.             "ti",    & TI,
  1312.             "te",    & TE,
  1313.             "cm",    & CM,
  1314.             "ce",    & CE,
  1315.             "dl",    & DL,
  1316.             "al",    & AL,
  1317.             "cl",    & CL,
  1318.             "pc",    & pcstr,
  1319.             NULL,    NULL
  1320.             };
  1321.  
  1322.     AM = tgetflag ("am");        /* only boolean se needs */
  1323.  
  1324.     /* get string values */
  1325.  
  1326.     for (i = 0; table[i].name != NULL; i++)
  1327.         *(table[i].ptr_to_cap) = tgetstr (table[i].name, & addr_caps);
  1328. }
  1329.  
  1330.  
  1331. /* setcaps -- get the capabilities from termcap file into termbuf */
  1332.  
  1333. setcaps (term)
  1334. char *term;
  1335. {
  1336.     switch (tgetent (termbuf, term)) {
  1337.     case -1:
  1338.         ttynormal ();
  1339.         fprintf (stderr, "se: couldn't open termcap file.\n");
  1340.         return (ERR);
  1341.  
  1342.     case 0:
  1343.         ttynormal ();
  1344.         fprintf (stderr, "se: no termcap entry for %s terminals.\n", term);
  1345.         return (ERR);
  1346.  
  1347.     case 1:
  1348.         break;
  1349.  
  1350.     default:
  1351.         error ("in setcaps: can't happen.\n");
  1352.     }
  1353.  
  1354.     return (OK);
  1355. }
  1356.  
  1357. #else
  1358.  
  1359. /* use the new terminfo package */
  1360. /*
  1361.  * Do NOT include <curses.h>, since it redefines
  1362.  * USG, ERR, and OK, to values inconsisten with what
  1363.  * we use.
  1364.  */
  1365.  
  1366. /* fix a problem in /usr/include/term.h */
  1367. #include <termio.h>
  1368. typedef struct termio SGTTY;
  1369.  
  1370. #include <term.h>    /* should be all we really need */
  1371.  
  1372. #define AM    auto_right_margin
  1373. #define TI    enter_ca_mode
  1374. #define TE    exit_ca_mode
  1375. #define VS    cursor_visible
  1376. #define VE    cursor_normal
  1377. #define CL    clear_screen
  1378. #define CE    clr_eol
  1379. #define DL    delete_line
  1380. #define AL    insert_line
  1381.  
  1382. /* setcaps --- called from main() to get capabilities */
  1383.  
  1384. setcaps (term)
  1385. char *term;
  1386. {
  1387.     int ret = 0;
  1388.  
  1389.     setupterm (term, 1, & ret);
  1390.     if (ret != 1)
  1391.         return (ERR);
  1392.     Nrows = lines;
  1393.     Ncols = columns;
  1394.     return (OK);
  1395. }
  1396.  
  1397. #endif
  1398.  
  1399. /* outc -- write a character to the terminal */
  1400.  
  1401. int outc (c)
  1402. char c;
  1403. {
  1404.     twrite (1, &c, 1);
  1405. }
  1406.  
  1407. /* t_init -- put out terminal initialization string */
  1408.  
  1409. t_init ()
  1410. {
  1411.     if (VS)
  1412.         tputs (VS, 1, outc);
  1413.     if (TI)
  1414.         tputs (TI, 1, outc);    /* terminal initializations */
  1415. }
  1416.  
  1417. /* t_exit -- put out strings to turn off whatever modes we had turned on */
  1418.  
  1419. t_exit ()
  1420. {
  1421.     /* terminal exiting strings */
  1422.     if (TE)
  1423.         tputs (TE, 1, outc);
  1424.     if (VE)
  1425.         tputs (VE, 1, outc);
  1426.     tflush ();    /* force it out */
  1427. }
  1428. #endif
  1429.  
  1430. /* send --- send a printable character, predict cursor position */
  1431.  
  1432. send (chr)
  1433. char chr;
  1434. {
  1435.     if (Currow == Nrows - 1 && Curcol == Ncols - 1)
  1436.         return;         /* anything in corner causes scroll... */
  1437.  
  1438. #ifndef HARD_TERMS
  1439.     outc (chr);
  1440. #else
  1441.     twrite (1, &chr, 1);
  1442. #endif
  1443.  
  1444.     if (Curcol == Ncols - 1)
  1445.     {
  1446. #ifndef HARD_TERMS
  1447.         if (AM)        /* terminal wraps when hits last column */
  1448. #else
  1449.         if (Term_type != TVT && Term_type != NETRON
  1450.             && Term_type != ESPRIT && Term_type != VI300)
  1451. #endif
  1452.         {
  1453.             Curcol = 0;
  1454.             Currow++;
  1455.         }
  1456.     }
  1457.     else        /* cursor not at extreme right */
  1458.         Curcol++;
  1459. }
  1460.  
  1461. /* terminal handling functions used throughout the editor */
  1462.  
  1463. /* clrscreen --- clear entire screen */
  1464.  
  1465. clrscreen ()
  1466. {
  1467.     Curcol = Currow = 0;
  1468.     /* clearing screen homes cursor to upper left corner */
  1469.     /* on all terminals */
  1470.  
  1471. #ifndef HARD_TERMS
  1472.     tputs (CL, 1, outc);
  1473. #else
  1474.     switch (Term_type) {
  1475.     case ADDS980:
  1476.     case ADDS100:
  1477.     case GT40:
  1478.     case CG:
  1479.     case ISC8001:
  1480.     case ANP:
  1481.     case NETRON:
  1482.         twrite (1, "\014", 1);
  1483.         break;
  1484.     case FOX:
  1485.         twrite (1, "\033K", 2);        /* clear display and all tabs */
  1486.         break;
  1487.     case TVT:
  1488.         twrite (1, "\014\017", 2);    /* home, erase to end of screen */
  1489.         break;
  1490.     case BEE150:
  1491.     case BEE200:
  1492.     case SBEE:
  1493.     case SOL:
  1494.     case H19:
  1495.         twrite (1, "\033E", 2);
  1496.         break;
  1497.     case HAZ1510:
  1498.     case ESPRIT:
  1499.         twrite (1, "\033\034", 2);
  1500.         break;
  1501.     case ADM3A:
  1502.     case VC4404:
  1503.     case TVI950:
  1504.         twrite (1, "\032", 1);
  1505.         break;
  1506.     case TS1:
  1507.         twrite (1, "\033*", 2);
  1508.         break;
  1509.     case ADM31:
  1510.         twrite (1, "\033+", 2);
  1511.         break;
  1512.     case IBM:
  1513.         twrite (1, "\033L", 2);
  1514.         break;
  1515.     case HP21:
  1516.         twrite (1, "\033H\033J", 4);    /* home cursor, erase to end of screen */
  1517.         break;
  1518.     case TRS80:
  1519.         twrite (1, "\034\037", 2);
  1520.         break;
  1521.     case VI200:
  1522.         twrite (1, "\033v", 2);
  1523.         break;
  1524.     case VI300:
  1525.         twrite (1, "\033[H\033[J", 6);
  1526.         /* home cursor, clear screen */
  1527.         break;
  1528.     case VI50:
  1529.         twrite (1, "\033v", 2);
  1530.         senddelay (30);
  1531.         break;
  1532.     }
  1533.  
  1534.     senddelay (20);
  1535. #endif
  1536. }
  1537.  
  1538.  
  1539. /* position_cursor --- position terminal's cursor to (row, col) */
  1540.  
  1541. position_cursor (row, col)
  1542. int row, col;
  1543. {
  1544.     if (row < Nrows && row >= 0        /* within vertical range? */
  1545.         && col < Ncols && col >= 0        /* within horizontal range? */
  1546.         && (row != Currow || col != Curcol))/* not already there? */
  1547. #ifndef HARD_TERMS
  1548.     {
  1549.         if (row == Currow && abs (Curcol - col) <= 4)
  1550.         {
  1551.             /* short motion in current line */
  1552.             if (Curcol < col)
  1553.                 for (; Curcol != col; Curcol++)
  1554.                     twrite (1, &Screen_image[Currow][Curcol], 1);
  1555.             else
  1556.                 for (; Curcol != col; Curcol--)
  1557.                     twrite (1, "\b", 1);
  1558.         }
  1559.         else
  1560.         {
  1561. #if defined (USG) && defined(S5R2)
  1562.             tputs (tparm (cursor_address, row, col), 1, outc);
  1563. #else
  1564.             tputs (tgoto (CM, col, row), 1, outc);
  1565. #endif
  1566.             Currow = row;
  1567.             Curcol = col;
  1568.         }
  1569.     }
  1570. #else
  1571.         switch (Term_type) {
  1572.         case ADDS980:
  1573.             addspos (row, col);
  1574.             break;
  1575.         case ADDS100:
  1576.             regentpos (row, col);
  1577.             break;
  1578.         case HP21:
  1579.             hp21pos (row, col);
  1580.             break;
  1581.         case FOX:
  1582.             pepos (row, col);
  1583.             break;
  1584.         case TVT:
  1585.             tvtpos (row, col);
  1586.             break;
  1587.         case GT40:
  1588.             gt40pos (row, col);
  1589.             break;
  1590.         case BEE150:
  1591.         case BEE200:
  1592.         case SBEE:
  1593.         case SOL:
  1594.             beepos (row, col);
  1595.             break;
  1596.         case VC4404:
  1597.             vcpos (row, col);
  1598.             break;
  1599.         case HAZ1510:
  1600.             hazpos (row, col);
  1601.             break;
  1602.         case ESPRIT:
  1603.             espritpos (row, col);
  1604.             break;
  1605.         case CG:
  1606.             cgpos (row, col);
  1607.             break;
  1608.         case ISC8001:
  1609.             iscpos (row, col);
  1610.             break;
  1611.         case ADM3A:
  1612.         case ADM31:
  1613.         case TS1:
  1614.         case TVI950:
  1615.             admpos (row, col);
  1616.             break;
  1617.         case IBM:
  1618.             ibmpos (row, col);
  1619.             break;
  1620.         case ANP:
  1621.             anppos (row, col);
  1622.             break;
  1623.         case NETRON:
  1624.             netpos (row, col);
  1625.             break;
  1626.         case H19:
  1627.             h19pos (row, col);
  1628.             break;
  1629.         case TRS80:
  1630.             trspos (row, col);
  1631.             break;
  1632.         case VI200:  
  1633.         case VI50:
  1634.             vipos (row, col);
  1635.             break;
  1636.         case VI300:
  1637.             ansipos (row, col);
  1638.             break;
  1639.         }
  1640. #endif
  1641. }
  1642.  
  1643.  
  1644. /* setscreen --- initialize screen and associated descriptive variables */
  1645.  
  1646. setscreen ()
  1647. {
  1648.     register int row, col;
  1649.  
  1650. #ifndef HARD_TERMS
  1651.     char *getenv ();
  1652.  
  1653. #if defined (BSD) || !defined (S5R2)
  1654.     setterm (getenv ("TERM"));
  1655. #endif
  1656.  
  1657.     t_init ();    /* put out the 'ti' and 'vs' capabilities */
  1658. #else
  1659.     switch (Term_type) {
  1660.     case ADDS980: 
  1661.     case FOX: 
  1662.     case HAZ1510: 
  1663.     case ADDS100:
  1664.     case BEE150: 
  1665.     case ADM3A: 
  1666.     case IBM: 
  1667.     case HP21: 
  1668.     case H19:
  1669.     case ADM31: 
  1670.     case VI200: 
  1671.     case VC4404: 
  1672.     case ESPRIT: 
  1673.     case TS1:
  1674.     case TVI950: 
  1675.     case VI50: 
  1676.     case VI300:
  1677.         Nrows = 24;
  1678.         Ncols = 80;
  1679.         break;
  1680.     case ANP:
  1681.         Nrows = 24;
  1682.         Ncols = 96;
  1683.         break;
  1684.     case SOL: 
  1685.     case NETRON: 
  1686.     case TRS80:
  1687.         Nrows = 16;
  1688.         Ncols = 64;
  1689.         break;
  1690.     case TVT:
  1691.         Nrows = 16;
  1692.         Ncols = 63;
  1693.         break;
  1694.     case GT40:
  1695.         Nrows = 32;
  1696.         Ncols = 73;
  1697.         break;
  1698.     case CG:
  1699.         Nrows = 51;
  1700.         Ncols = 85;
  1701.         break;
  1702.     case ISC8001:
  1703.         Nrows = 48;
  1704.         Ncols = 80;
  1705.         break;
  1706.     case BEE200: 
  1707.     case SBEE:
  1708.         Nrows = 25;
  1709.         Ncols = 80;
  1710.         break;
  1711.     }
  1712. #endif
  1713.     clrscreen ();    /* clear physical screen, set cursor position */
  1714.  
  1715.     Toprow = 0;
  1716.     Botrow = Nrows - 3; /* 1 for 0-origin, 1 for status, 1 for cmd */
  1717.     Cmdrow = Botrow + 1;
  1718.     Topln = 1;
  1719.     Sclen = -1;         /* make sure we assume nothing on the screen */
  1720.  
  1721.     for (row = 0; row < Nrows; row++)    /* now clear virtual screen */
  1722.         for (col = 0; col < Ncols; col++)
  1723.             Screen_image[row][col] = ' ';
  1724.  
  1725.     for (col = 0; col < Ncols; col++)    /* and clear out status line */
  1726.         Msgalloc[col] = NOMSG;
  1727.  
  1728.     Insert_mode = NO;
  1729. }
  1730.  
  1731.  
  1732. /* inslines --- insert 'n' lines on the screen at 'row' */
  1733.  
  1734. inslines (row, n)
  1735. int row, n;
  1736. {
  1737.     register int i;
  1738.     int delay;
  1739.  
  1740.     position_cursor (row, 0);
  1741. #ifdef HARD_TERMS
  1742.     if (Term_type == VI300)
  1743.     {
  1744.         char pseq[10];
  1745.         register int pp = 0;
  1746.         pseq[pp++] = '\033';
  1747.         pseq[pp++] = '[';
  1748.         if (n >= 10)
  1749.             pseq[pp++] = '0' + n / 10;
  1750.         pseq[pp++] = '0' + n % 10;
  1751.         pseq[pp++] = 'L';
  1752.         twrite (1, pseq, pp);
  1753.         delay = 0;
  1754.     }
  1755.     else
  1756. #endif
  1757.         for (i = 0; i < n; i++)
  1758.         {
  1759. #ifndef HARD_TERMS
  1760.             tputs (AL, n, outc);
  1761.             tflush ();
  1762. #else
  1763.             switch (Term_type) {
  1764.             case VI200:
  1765.                 twrite (1, "\033L", 2);
  1766.                 delay = 0;
  1767.                 break;
  1768.             case VI50:
  1769.             case H19:
  1770.                 twrite (1, "\033L", 2);
  1771.                 delay = 32;
  1772.                 break;
  1773.             case ESPRIT:
  1774.                 twrite (1, "\033\032", 2);
  1775.                 delay = 32;
  1776.                 break;
  1777.             case TS1:
  1778.             case TVI950:
  1779.                 twrite (1, "\033E", 2);
  1780.                 delay = 0;
  1781.                 break;
  1782.             case ADDS100:
  1783.                 twrite (1, "\033M", 2);
  1784.                 delay = 96;
  1785.                 break;
  1786.             default:
  1787.                 error ("in inslines: shouldn't happen");
  1788.             }
  1789.  
  1790.             if (delay != 0)
  1791.                 senddelay (delay);
  1792. #endif
  1793.         }
  1794.  
  1795.     for (i = Nrows - 1; i - n >= Currow; i--)
  1796.         move_ (Screen_image[i - n], Screen_image[i], Ncols);
  1797.  
  1798.     for (; i >= Currow; i--)
  1799.         move_ (Blanks, Screen_image[i], Ncols);
  1800. }
  1801.  
  1802.  
  1803. /* dellines --- delete 'n' lines beginning at 'row' */
  1804.  
  1805. dellines (row, n)
  1806. int row, n;
  1807. {
  1808.     register int i;
  1809.     int delay;
  1810.  
  1811.     position_cursor (row, 0);
  1812. #ifdef HARD_TERMS
  1813.     if (Term_type == VI300)
  1814.     {
  1815.         char pseq[10];
  1816.         register int pp = 0;
  1817.         pseq[pp++] = '\033';
  1818.         pseq[pp++] = '[';
  1819.         if (n >= 10)
  1820.             pseq[pp++] = '0' + n / 10;
  1821.         pseq[pp++] = '0' + n % 10;
  1822.         pseq[pp++] = 'M';
  1823.         twrite (1, pseq, pp);
  1824.         delay = 0;
  1825.     }
  1826.     else
  1827. #endif
  1828.         for (i = 0; i < n; i++)
  1829.         {
  1830. #ifndef HARD_TERMS
  1831.             tputs (DL, n, outc);
  1832.             tflush ();
  1833. #else
  1834.             switch (Term_type) {
  1835.             case VI200:
  1836.                 twrite (1, "\033M", 2);
  1837.                 delay = 0;
  1838.                 break;
  1839.             case VI50:
  1840.                 twrite (1, "\033M", 2);
  1841.                 delay = 32;
  1842.                 break;
  1843.             case H19:
  1844.                 twrite (1, "\033M", 2);
  1845.                 delay = 32;
  1846.                 break;
  1847.             case TS1:
  1848.             case TVI950:
  1849.                 twrite (1, "\033R", 2);
  1850.                 delay = 0;
  1851.                 break;
  1852.             case ESPRIT:
  1853.                 twrite (1, "\033\023", 2);
  1854.                 delay = 32;
  1855.                 break;
  1856.             case ADDS100:
  1857.                 twrite (1, "\033l", 2);
  1858.                 delay = 96;
  1859.                 break;
  1860.             default:
  1861.                 error ("in dellines: shouldn't happen");
  1862.             }
  1863.  
  1864.             if (delay != 0)
  1865.                 senddelay (delay);
  1866. #endif
  1867.         }
  1868.  
  1869.     for (i = Currow; i + n < Nrows; i++)
  1870.         move_ (Screen_image[i + n], Screen_image[i], Ncols);
  1871.  
  1872.     for (; i < Nrows; i++)
  1873.         move_ (Blanks, Screen_image[i], Ncols);
  1874. }
  1875.  
  1876.  
  1877. /* hwinsdel --- return 1 if the terminal has hardware insert/delete */
  1878.  
  1879. int hwinsdel ()
  1880. {
  1881.     if (No_hardware == YES)
  1882.         return (NO);
  1883.  
  1884. #ifndef HARD_TERMS
  1885.     return (AL != NULL && DL != NULL);
  1886. #else
  1887.     switch (Term_type) {
  1888.     case VI300:
  1889.     case VI200:
  1890.     case VI50:
  1891.     case ESPRIT:
  1892.     case H19:
  1893.     case TS1:
  1894.     case TVI950:
  1895.     case ADDS100:
  1896.         return 1;
  1897.     }
  1898.     return 0;
  1899. #endif
  1900. }
  1901.  
  1902.  
  1903. /* clear_to_eol --- clear screen to end-of-line */
  1904.  
  1905. clear_to_eol (row, col)
  1906. int row, col;
  1907. {
  1908.     register int c, flag; 
  1909. #ifdef HARD_TERMS
  1910.     register int hardware;
  1911.  
  1912.     switch (Term_type) {
  1913.     case BEE200:
  1914.     case BEE150:
  1915.     case FOX:
  1916.     case SBEE:
  1917.     case ADDS100:
  1918.     case HP21:
  1919.     case IBM:
  1920.     case ANP:
  1921.     case NETRON:
  1922.     case H19:
  1923.     case TS1:
  1924.     case TRS80:
  1925.     case ADM31:
  1926.     case VI200:
  1927.     case VI300:
  1928.     case VI50:
  1929.     case VC4404:
  1930.     case ESPRIT:
  1931.     case TVI950:
  1932.         hardware = YES;
  1933.         break;
  1934.     default:
  1935.         hardware = NO;
  1936.         if (Term_type == ADDS980 && row < Nrows - 1)
  1937.             hardware = YES;
  1938.         if (Term_type == TVT && row > 0)
  1939.             hardware = YES;
  1940.     }
  1941. #endif
  1942.  
  1943.     flag = NO;
  1944.  
  1945.     for (c = col; c < Ncols; c++)
  1946.         if (Screen_image[row][c] != ' ')
  1947.         {
  1948.             Screen_image[row][c] = ' ';
  1949. #ifndef HARD_TERMS
  1950.             if (CE != NULL)        /* there is hardware */
  1951. #else
  1952.             if (hardware == YES)
  1953. #endif
  1954.                 flag = YES;
  1955.             else
  1956.             {
  1957.                 position_cursor (row, c);
  1958.                 send (' ');
  1959.             }
  1960.         }
  1961.  
  1962.     if (flag == YES)
  1963.     {
  1964.         position_cursor (row, col);
  1965. #ifndef HARD_TERMS
  1966.         tputs (CE, 1, outc);
  1967. #else
  1968.         switch (Term_type) {
  1969.         case BEE200: 
  1970.         case BEE150:
  1971.         case SBEE:
  1972.         case ADDS100:
  1973.         case HP21:
  1974.         case H19:
  1975.         case VC4404:
  1976.         case TS1:
  1977.         case TVI950:
  1978.         case VI50:
  1979.             twrite (1, "\033K", 2);
  1980.             break;
  1981.         case FOX:
  1982.         case IBM:
  1983.             twrite (1, "\033I", 2);
  1984.             break;
  1985.         case ADDS980:
  1986.             twrite (1, "\n", 1);
  1987.             Currow++;
  1988.             Curcol = 0;
  1989.             break;
  1990.         case ANP:
  1991.             twrite (1, "\033L", 2);
  1992.             break;
  1993.         case NETRON:
  1994.             twrite (1, "\005", 1);
  1995.             break;
  1996.         case TRS80:
  1997.             twrite (1, "\036", 1);
  1998.             break;
  1999.         case ADM31:
  2000.             twrite (1, "\033T", 2);
  2001.             break;
  2002.         case VI200:
  2003.             twrite (1, "\033x", 2);
  2004.             break;
  2005.         case VI300:
  2006.             twrite (1, "\033[K", 3);
  2007.             break;
  2008.         case ESPRIT:
  2009.             twrite (1, "\033\017", 2);
  2010.             break;
  2011.         case TVT:
  2012.             twrite (1, "\013\012", 2);
  2013.             break;
  2014.         } /* end switch */
  2015. #endif
  2016.     } /* end if (flag == YES) */
  2017. } /* end clear_to_eol */
  2018.  
  2019.  
  2020. #ifdef HARD_TERMS
  2021.  
  2022. /* begin terminal dependant routines */
  2023.  
  2024. /* addspos --- position cursor to (row, col) on ADDS Consul 980 */
  2025.  
  2026. static addspos (row, col)
  2027. int row, col;
  2028. {
  2029.     char coord;
  2030.     int ntabs, where;
  2031.  
  2032.     if (Currow != row || col < Curcol - 7)
  2033.     {
  2034.         twrite (1, "\013", 1);    /* VT */
  2035.         coord = '@' + row;
  2036.         twrite (1, &coord, 1);
  2037.         Currow = row;
  2038.         Curcol = 0;
  2039.     }
  2040.  
  2041.     if (col > Curcol + 2)
  2042.     {
  2043.         ntabs = (col + 2) / 5;    /* from beginning */
  2044.         where = ntabs * 5;
  2045.         ntabs -= Curcol / 5;    /* from Curcol */
  2046.         if (ntabs + abs (where - col) <= 4)
  2047.         {
  2048.             for (; ntabs > 0; ntabs--)
  2049.                 twrite (1, "\t", 1);
  2050.             Curcol = where;
  2051.         }
  2052.     }
  2053.  
  2054.     if (col > Curcol + 4)
  2055.     {
  2056.         where = col - Curcol;
  2057.         twrite (1, "\033\005", 2);    /* ESC ENQ */
  2058.         coord = '0' + (where / 10);
  2059.         twrite (1, &coord, 1);
  2060.         coord = '0' + (where % 10);
  2061.         twrite (1, &coord, 1);
  2062.         Curcol = col;
  2063.     }
  2064.  
  2065.     while (Curcol < col)
  2066.     {
  2067.         twrite (1, &Screen_image[Currow][Curcol], 1);
  2068.         Curcol++;
  2069.     }
  2070.  
  2071.     while (Curcol > col)
  2072.     {
  2073.         twrite (1, "\b", 1);
  2074.         Curcol--;
  2075.     }
  2076. }
  2077.  
  2078. /* admpos --- position cursor to (row, col) on ADM-3A and ADM-31 terminals */
  2079.  
  2080. static admpos (row, col)
  2081. int row, col;
  2082. {
  2083.     int dist;
  2084.     char coord;
  2085.  
  2086.     dist = col - Curcol;
  2087.     if (dist < 0)
  2088.         dist = -dist;
  2089.     if (row == Currow && dist < 4)  /* 4 chars for abs. position */
  2090.     {
  2091.         while (Curcol < col)
  2092.         {
  2093.             twrite (1, &Screen_image[Currow][Curcol], 1);
  2094.             Curcol++;
  2095.         }
  2096.         while (Curcol > col)
  2097.         {
  2098.             twrite (1, "\b", 1);
  2099.             Curcol--;
  2100.         }
  2101.     }
  2102.     else
  2103.     {
  2104.         twrite (1, "\033=", 2);
  2105.         coord = row + ' ';
  2106.         twrite (1, &coord, 1);
  2107.         coord = col + ' ';
  2108.         twrite (1, &coord, 1);
  2109.         Currow = row;
  2110.         Curcol = col;
  2111.     }
  2112. }
  2113.  
  2114.  
  2115.  
  2116. /* ansipos --- position cursor on ANSI X something-or-other terminals */
  2117.  
  2118. static ansipos (row, col)
  2119. register int row, col;
  2120. {
  2121.     register int dist;
  2122.  
  2123.     char absseq[20], relseq[50];
  2124.     int absp = 0;
  2125.     register int relp = 0;
  2126.     register int trow, tcol;
  2127.  
  2128.     /*** Build relative positioning string--handle row first ***/
  2129.     trow = Currow; 
  2130.     tcol = Curcol;
  2131.     if (row >= trow && row <= trow + 3)
  2132.         for (; trow < row; trow++)
  2133.             relseq[relp++] = '\012';
  2134.     else if (row < trow && row >= trow - 1)
  2135.         for (; trow > row; trow--)
  2136.         { 
  2137.             relseq[relp++] = '\033'; 
  2138.             relseq[relp++] = 'M'; 
  2139.         }
  2140.     else if (row >= trow)
  2141.     {
  2142.         relseq[relp++] = '\033';
  2143.         relseq[relp++] = '[';
  2144.         dist = row - trow;
  2145.         if (dist >= 10)
  2146.             relseq[relp++] = '0' + dist / 10;
  2147.         relseq[relp++] = '0' + dist % 10;
  2148.         relseq[relp++] = 'B';
  2149.         trow = row;
  2150.     }
  2151.     else /* row < trow */
  2152.     {
  2153.         relseq[relp++] = '\033';
  2154.         relseq[relp++] = '[';
  2155.         dist = trow - row;
  2156.         if (dist >= 10)
  2157.             relseq[relp++] = '0' + dist / 10;
  2158.         relseq[relp++] = '0' + dist % 10;
  2159.         relseq[relp++] = 'A';
  2160.         trow = row;
  2161.     }
  2162.  
  2163.     /*** Now do the column part of relative positioning ***/
  2164.     if (col >= tcol - 2 && col <= tcol + 2)
  2165.         ;       /* skip coarse positioning -- just do the fine stuff */
  2166.     else
  2167.     {
  2168.         if (col <= 4)
  2169.         {
  2170.             relseq[relp++] = '\015';
  2171.             tcol = 0;
  2172.         }
  2173.         dist = col - tcol;
  2174.         if (col < 72 && dist > 2
  2175.             && dist < 8 && (col + 1) % 8 <= 2)
  2176.         {
  2177.             relseq[relp++] = '\t';
  2178.             tcol = ((tcol + 8) / 8) * 8;
  2179.         }
  2180.     }
  2181.     dist = col - tcol;
  2182.     if (dist < 0)
  2183.         dist = -dist;
  2184.     if (dist == 0)
  2185.         ;
  2186.     else if (dist < 4)  /* 4 chars for abs. position */
  2187.     {
  2188.         while (tcol < col)
  2189.         {
  2190.             relseq[relp++] = Screen_image[trow][tcol];
  2191.             tcol++;
  2192.         }
  2193.         while (tcol > col)
  2194.         {
  2195.             relseq[relp++] = '\b';
  2196.             tcol--;
  2197.         }
  2198.     }
  2199.     else if (col >= tcol)
  2200.     {
  2201.         relseq[relp++] = '\033';
  2202.         relseq[relp++] = '[';
  2203.         if (dist >= 10)
  2204.             relseq[relp++] = '0' + dist / 10;
  2205.         relseq[relp++] = '0' + dist % 10;
  2206.         relseq[relp++] = 'C';
  2207.         tcol = col;
  2208.     }
  2209.     else /* if (col < tcol) */
  2210.     {
  2211.         relseq[relp++] = '\033';
  2212.         relseq[relp++] = '[';
  2213.         if (dist >= 10)
  2214.             relseq[relp++] = '0' + dist / 10;
  2215.         relseq[relp++] = '0' + dist % 10;
  2216.         relseq[relp++] = 'D';
  2217.         tcol = col;
  2218.     }
  2219.  
  2220.     /*** If relative positioning will do it, forget absolute ***/
  2221.     if (relp <= 5)
  2222.         twrite (1, relseq, relp);
  2223.     else
  2224.     {
  2225.         absseq[absp++] = '\033';
  2226.         absseq[absp++] = '[';
  2227.         if (row >= 9)
  2228.             absseq[absp++] = '0' + (row + 1) / 10;
  2229.         absseq[absp++] = '0' + (row + 1) % 10;
  2230.         absseq[absp++] = ';';
  2231.         if (col >= 9)
  2232.             absseq[absp++] = '0' + (col + 1) / 10;
  2233.         absseq[absp++] = '0' + (col + 1) % 10;
  2234.         absseq[absp++] = 'H';
  2235.         if (absp >= relp)
  2236.             twrite (1, relseq, relp);
  2237.         else
  2238.             twrite (1, absseq, absp);
  2239.     }
  2240.     Curcol = col;
  2241.     Currow = row;
  2242. }
  2243.  
  2244.  
  2245.  
  2246. /* anppos --- position cursor on Allen & Paul model 1 */
  2247.  
  2248. static anppos (row, col)
  2249. int row, col;
  2250. {
  2251.     register char coord;
  2252.  
  2253.     if (row == Currow)      /* if close, just sneak right or left */
  2254.     {
  2255.         if (col == Curcol + 1)
  2256.             twrite (1, "\t", 1);
  2257.         else if (col == Curcol + 2)
  2258.             twrite (1, "\t\t", 2);
  2259.         else if (col == Curcol - 1)
  2260.             twrite (1, "\b", 1);
  2261.         else if (col == Curcol - 2)
  2262.             twrite (1, "\b\b", 2);
  2263.         else
  2264.         {
  2265.             twrite (1, "\033C", 2);
  2266.             coord = col + ' ';
  2267.             twrite (1, &coord, 1);
  2268.         }
  2269.     }
  2270.  
  2271.     else if (col == Curcol) /* if close, sneak up or down */
  2272.     {
  2273.         if (row == Currow + 1)
  2274.             twrite (1, "\012", 1);
  2275.         else if (row == Currow + 2)
  2276.             twrite (1, "\012\012", 2);
  2277.         else if (row == Currow - 1)
  2278.             twrite (1, "\013", 1);
  2279.         else if (row == Currow - 2)
  2280.             twrite (1, "\013\013", 2);
  2281.         else
  2282.         {
  2283.         /* because of bug in anp software, abs row pos is not working.
  2284.          * the following code was replaced to compensate:
  2285.          *
  2286.          *          twrite (1, "\033R", 2);
  2287.          *          coord = row + ' ';
  2288.          *          twrite (1, &coord, 1);
  2289.          */
  2290.             twrite (1, "\033P", 2);
  2291.             coord = row + ' ';
  2292.             twrite (1, &coord, 1);
  2293.             coord = col + ' ';
  2294.             twrite (1, &coord, 1);
  2295.         }
  2296.     }
  2297.     else    /* resort to absolute positioning */
  2298.     {
  2299.         twrite (1, "\033P", 2);
  2300.         coord = row + ' ';
  2301.         twrite (1, &coord, 1);
  2302.         coord = col + ' ';
  2303.         twrite (1, &coord, 1);
  2304.     }
  2305.  
  2306.     Currow = row;
  2307.     Curcol = col;
  2308. }
  2309.  
  2310. /* b200coord --- transmit a coordinate for Beehive 200 cursor addressing */
  2311.  
  2312. static b200coord (coord)
  2313. int coord;
  2314. {
  2315.     char acc;
  2316.     int tens, units;
  2317.  
  2318.     tens = coord / 10;
  2319.     units = coord - 10 * tens;
  2320.     acc = units + 16 * tens;
  2321.  
  2322.     twrite (1, & acc, 1);
  2323. }
  2324.  
  2325. /* beepos --- position cursor on Beehive terminal */
  2326.  
  2327. static beepos (row, col)
  2328. int row, col;
  2329. {
  2330.     if (row == Currow + 1 && col == 0 && Term_type != SBEE)
  2331.     {
  2332.         twrite (1, "\r\n", 2);        /*  CR LF */
  2333.         Curcol = 0;
  2334.         Currow++;
  2335.     }
  2336.     else if (row == 0 && col == 0)        /* home cursor */
  2337.     {
  2338.         twrite (1, "\033H", 2);
  2339.         Currow = Curcol = 0;
  2340.     }
  2341.     else if (row == Currow && col > Curcol && col <= Curcol + 4)
  2342.         while (Curcol != col)
  2343.         {
  2344.             twrite (1, &Screen_image[Currow][Curcol], 1);
  2345.             Curcol++;
  2346.         }
  2347.     else if (row == Currow && col < Curcol && col >= Curcol - 4)
  2348.         while (Curcol != col)
  2349.         {
  2350.             twrite (1, "\b", 1);
  2351.             Curcol--;
  2352.         }
  2353.     else        /* resort to absolute addressing */
  2354.     {
  2355.         twrite (1, "\033F", 2);
  2356.         if (Term_type == BEE200 || Term_type == SOL)
  2357.         {
  2358.             b200coord (row);
  2359.             b200coord (col);
  2360.         }
  2361.         else if (Term_type == BEE150)
  2362.         {
  2363.             char r, c;
  2364.  
  2365.             r = row + ' ';
  2366.             c = col + ' ';
  2367.             twrite (1, &r, 1);
  2368.             twrite (1, &c, 1);
  2369.         }
  2370.         else        /* is superbee */
  2371.         {
  2372.             sbeecoord (col);
  2373.             sbeecoord (row);
  2374.         }
  2375.  
  2376.         Currow = row;
  2377.         Curcol = col;
  2378.     }
  2379. }
  2380.  
  2381. /* cgpos --- position cursor on Chromatics CG */
  2382.  
  2383. static cgpos (row, col)
  2384. int row, col;
  2385. {
  2386.     char i, j;
  2387.  
  2388.     if (row == Currow + 1 && col == 0)
  2389.     {
  2390.         twrite (1, "\r\n", 2);        /* CR LF */
  2391.         Curcol = 0;
  2392.         Currow++;
  2393.     }
  2394.     else if (row == 0 && col == 0)        /* home cursor */
  2395.     {
  2396.         twrite (1, "\034", 1);    /* FS */
  2397.         Currow = Curcol = 0;
  2398.     }
  2399.     else if (row == Currow && col > Curcol && col <= Curcol + 7)
  2400.         while (Curcol != col)
  2401.         {
  2402.             twrite (1, "\035", 1);    /* GS */
  2403.             Curcol++;
  2404.         }
  2405.     else if (row == Currow && col < Curcol && col >= Curcol - 7)
  2406.         while (Curcol != col)
  2407.         {
  2408.             twrite (1, "\b", 1);
  2409.             Curcol--;
  2410.         }
  2411.     else
  2412.     {
  2413.         /* resort to absolute addressing */
  2414.         twrite (1, "\001U", 2);        /* SOH U */
  2415.         i = 511 - (10 * row);
  2416.         j = 6 * col;
  2417.         cgcoord (j);
  2418.         cgcoord (i);
  2419.         Currow = row;
  2420.         Curcol = col;
  2421.     }
  2422.  
  2423. }
  2424.  
  2425.  
  2426. /* cgcoord --- output a decimal coordinate for Chromatics CG */
  2427.  
  2428. static cgcoord (i)
  2429. int i;
  2430. {
  2431.     int units, tens, hundreds;
  2432.     char coords[4];
  2433.  
  2434.     units = i % 10;
  2435.     i /= 10;
  2436.     tens = i % 10;
  2437.     i /= 10;
  2438.     hundreds = i % 10;
  2439.  
  2440.     coords[0] = hundreds + 16 + ' ';
  2441.     coords[1] = tens + 16 + ' ';
  2442.     coords[2] = units + 16 + ' ';
  2443.     coords[3] = EOS;
  2444.     twrite (1, coords, 3);
  2445. }
  2446.  
  2447.  
  2448.  
  2449. /* gt40pos --- position cursor to (row, col) on DEC GT40 with Waugh software */
  2450.  
  2451. static gt40pos (row, col)
  2452. int row, col;
  2453. {
  2454.     char coord;
  2455.  
  2456.     if (row != Currow && col != Curcol)    /* absolute positioning */
  2457.     {
  2458.         twrite (1, "\033", 1);
  2459.         coord = row + ' ';
  2460.         twrite (1, &coord, 1);
  2461.         coord = col + ' ';
  2462.         twrite (1, &coord, 1);
  2463.         Currow = row;
  2464.         Curcol = col;
  2465.     }
  2466.     else if (row != Currow)        /* col must = Curcol */
  2467.     {                /* vertical positioning */
  2468.         twrite (1, "\006", 1);    /* ACK */
  2469.         coord = row + ' ';
  2470.         twrite (1, &coord, 1);
  2471.         Currow = row;
  2472.     }
  2473.     else if (abs (col - Curcol) < 2)
  2474.         uhcm (col);
  2475.     else
  2476.     {
  2477.         twrite (1, "\025", 1);    /* NACK */
  2478.         coord = col + ' ';
  2479.         twrite (1, &coord, 1);
  2480.         Curcol = col;
  2481.     }
  2482. }
  2483.  
  2484.  
  2485.  
  2486. /* h19pos --- position cursor on Heath H19 (DEC VT52 compatible, supposedly) */
  2487.  
  2488. static h19pos (row, col)
  2489. int row, col;
  2490. {
  2491.     int dist;
  2492.     char coord;
  2493.  
  2494.     dist = col - Curcol;
  2495.     if (dist < 0)
  2496.         dist = -dist;
  2497.     if (row == Currow && dist < 4)  /* 4 chars for abs. position */
  2498.     {
  2499.         while (Curcol < col)
  2500.         {
  2501.             twrite (1, &Screen_image[Currow][Curcol], 1);
  2502.             Curcol++;
  2503.         }
  2504.         while (Curcol > col)
  2505.         {
  2506.             twrite (1, "\b", 1);
  2507.             Curcol--;
  2508.         }
  2509.     }
  2510.     else
  2511.     {
  2512.         twrite (1, "\033Y", 2);
  2513.         coord = row + ' ';
  2514.         twrite (1, &coord, 1);
  2515.         coord = col + ' ';
  2516.         twrite (1, &coord, 1);
  2517.         Currow = row;
  2518.         Curcol = col;
  2519.     }
  2520. }
  2521.  
  2522. /* hp21pos --- position cursor on HP 2621 terminal */
  2523.  
  2524. static hp21pos (row, col)
  2525. int row, col;
  2526. {
  2527.     int units, tens;
  2528.  
  2529.     if (row == Currow && col == 0)
  2530.     {
  2531.         twrite (1, "\r\n", 2);        /* CR LF */
  2532.         Curcol = 0;
  2533.         Currow++;
  2534.     }
  2535.     else if (row == 0 && col == 0)        /* home cursor */
  2536.     {
  2537.         twrite (1, "\033H", 2);
  2538.         Currow = Curcol = 0;
  2539.     }
  2540.     else if (row == Currow && col > Curcol && col <= Curcol + 4)
  2541.         while (Curcol != col)
  2542.         {
  2543.             twrite (1, &Screen_image[Currow][Curcol], 1);
  2544.             Curcol++;
  2545.         }
  2546.     else if (row == Currow && col < Curcol && col >= Curcol - 4)
  2547.         while (Curcol != col)
  2548.         {
  2549.             twrite (1, "\b", 1);
  2550.             Curcol--;
  2551.         }
  2552.     else if (2 * abs (Currow - row) + abs (Curcol - col) <= 7)
  2553.     {
  2554.         while (Currow < row)
  2555.         {
  2556.             twrite (1, "\033B", 2);
  2557.             Currow++;
  2558.         }
  2559.         while (Currow > row)
  2560.         {
  2561.             twrite (1, "\033A", 2);
  2562.             Currow--;
  2563.         }
  2564.         while (Curcol > col)
  2565.         {
  2566.             twrite (1, "\b", 1);
  2567.             Curcol--;
  2568.         }
  2569.         while (Curcol < col)
  2570.         {
  2571.             twrite (1, & Screen_image[Currow][Curcol], 1);
  2572.             Curcol++;
  2573.         }
  2574.     }
  2575.     else
  2576.     {
  2577.         /* resort to absolute addressing */
  2578.         char c;
  2579.  
  2580.         twrite (1, "\033&a", 3);
  2581.         units = row % 10;
  2582.         tens = row / 10;
  2583.         if (tens != 0)
  2584.         {
  2585.             c = tens + '0';
  2586.             twrite (1, &c, 1);
  2587.         }
  2588.         c = units + '0';
  2589.         twrite (1, &c, 1);
  2590.         twrite (1, "y", 1);
  2591.         units = col % 10;
  2592.         tens = col / 10;
  2593.         if (tens != 0)
  2594.         {
  2595.             c = tens + '0';
  2596.             twrite (1, &c, 1);
  2597.         }
  2598.         c = units + '0';
  2599.         twrite (1, &c, 1);
  2600.         twrite (1, "C", 1);
  2601.         Currow = row;
  2602.         Curcol = col;
  2603.     }
  2604. }
  2605.  
  2606.  
  2607. /* hazpos --- position cursor on Hazeltine 1510 */
  2608.  
  2609. static hazpos (row, col)
  2610. int row, col;
  2611. {
  2612.     int dist;
  2613.     char c;
  2614.  
  2615.     dist = col - Curcol;
  2616.     if (dist < 0)
  2617.         dist = -dist;
  2618.     if (row == Currow && dist < 4)  /* 4 chars for abs. position */
  2619.     {
  2620.         while (Curcol < col)
  2621.         {
  2622.             twrite (1, &Screen_image[Currow][Curcol], 1);
  2623.             Curcol++;
  2624.         }
  2625.         while (Curcol > col)
  2626.         {
  2627.             twrite (1, "\b", 1);
  2628.             Curcol--;
  2629.         }
  2630.     }
  2631.     else
  2632.     {
  2633.         twrite (1, "\033\021", 2);
  2634.         c = col;
  2635.         twrite (1, &c, 1);
  2636.         c = row;
  2637.         twrite (1, &c, 1);
  2638.         Currow = row;
  2639.         Curcol = col;
  2640.     }
  2641. }
  2642.  
  2643.  
  2644. /* ibmpos --- position cursor on IBM 3101 terminal */
  2645.  
  2646. static ibmpos (row, col)
  2647. int row, col;
  2648. {
  2649.     int dist;
  2650.     static char abspos[] = "\033\Y\0\0";
  2651.  
  2652.     dist = col - Curcol;
  2653.     if (dist < 0)
  2654.         dist = -dist;
  2655.     
  2656.     if (row == Currow && dist < 4)        /* 4 chars for abs pos */
  2657.     {
  2658.         while (Curcol < col)
  2659.         {
  2660.             twrite (1, & Screen_image[Currow][Curcol], 1);
  2661.             Curcol++;
  2662.         }
  2663.         while (Curcol > col)
  2664.         {
  2665.             twrite (1, "\b", 1);
  2666.             Curcol--;
  2667.         }
  2668.     }
  2669.     else
  2670.     {
  2671.         abspos[2] = row + ' ';
  2672.         abspos[3] = col + ' ';
  2673.         twrite (1, abspos, 4);
  2674.         Currow = row;
  2675.         Curcol = col;
  2676.     }
  2677. }
  2678.  
  2679.  
  2680.  
  2681. /* iscpos --- position cursor on ISC 8001 color terminal */
  2682.  
  2683. static iscpos (row, col)
  2684. int row, col;
  2685. {
  2686.     char r, c;
  2687.  
  2688.     if (row == 0 && col == 0)
  2689.         twrite (1, "\b", 1);
  2690.     else
  2691.     {
  2692.         twrite (1, "\003", 1);        /* ETX */
  2693.         r = row;
  2694.         c = col;
  2695.         twrite (1, & r, 1);
  2696.         twrite (1, & c, 1);
  2697.     }
  2698.  
  2699.     Currow = row;
  2700.     Curcol = col;
  2701. }
  2702.  
  2703. /* netpos --- position cursor on Netron terminal */
  2704.  
  2705. static netpos (row, col)
  2706. int row, col;
  2707. {
  2708.     static char abspos[] = "\033=\0\0";
  2709.  
  2710.     abspos[2] = (char) row;
  2711.     abspos[3] = (char) col;
  2712.     twrite (1, abspos, 4);
  2713.     Currow = row;
  2714.     Curcol = col;
  2715. }
  2716.  
  2717. /* pepos --- position cursor on Perkin-Elmer 550 & 1100 terminals */
  2718.  
  2719. static pepos (row, col)
  2720. int row, col;
  2721. {
  2722.     char coord;
  2723.  
  2724.     /* get on correct row first */
  2725.     if (Currow == row)
  2726.         ;        /* already on correct row; nothing to do */
  2727.     else if (row == Currow - 1)
  2728.     {
  2729.         twrite (1, "\033A", 2);        /* cursor up */
  2730.         Currow--;
  2731.     }
  2732.     else if (row == Currow + 1)
  2733.     {
  2734.         twrite (1, "\033B", 2);        /* cursor down */
  2735.         Currow++;
  2736.     }
  2737.     else
  2738.     {
  2739.         /* vertical absolute positioning */
  2740.         twrite (1, "\033X", 2);
  2741.         coord = row + ' ';
  2742.         twrite (1, & coord, 1);
  2743.     }
  2744.  
  2745.     /* now perform horizontal motion */
  2746.     if (abs (col - Curcol) > 3)    /* do absolute horizontal position */
  2747.     {
  2748.         twrite (1, "\033Y", 2);
  2749.         coord = col + ' ';
  2750.         twrite (1, &coord, 1);
  2751.         Curcol = col;
  2752.     }
  2753.     else
  2754.         uhcm (col);
  2755. }
  2756.  
  2757. /* sbeecoord --- transmit a coordinate for Superbee terminal */
  2758.  
  2759. static sbeecoord (coord)
  2760. int coord;
  2761. {
  2762.     char r, c;
  2763.  
  2764.     r = (coord / 10) + ' ';
  2765.     c = (coord % 10) + ' ';
  2766.     twrite (1, & r, 1);
  2767.     twrite (1, & c, 1);
  2768. }
  2769.  
  2770. /* trspos --- position cursor on TRS80 Model 1 */
  2771.  
  2772. static trspos (row, col)
  2773. int row, col;
  2774. {
  2775.     while (Currow != row)
  2776.     {
  2777.         if (Currow > row)
  2778.         {
  2779.             twrite (1, "\033", 1);
  2780.             Currow--;
  2781.         }
  2782.         else
  2783.         {
  2784.             twrite (1, "\032", 1);        /* SUB */
  2785.             Currow++;
  2786.         }
  2787.     }
  2788.  
  2789.     if (Curcol != col)
  2790.     {
  2791.         if (col > Curcol)
  2792.             while (col > Curcol)
  2793.             {
  2794.                 twrite (1, "\031", 1);    /* EM */
  2795.                 Curcol++;
  2796.             }
  2797.         else if (col < Curcol / 2)
  2798.         {
  2799.             twrite (1, "\035", 1);    /* GS */
  2800.             Curcol = 0;
  2801.             while (Curcol < col)
  2802.             {
  2803.                 twrite (1, "\031", 1);    /* EM */
  2804.                 Curcol++;
  2805.             }
  2806.         }
  2807.         else
  2808.             while (col < Curcol)
  2809.             {
  2810.                 twrite (1, "\030", 1);    /* CAN */
  2811.                 Curcol--;
  2812.             }
  2813.     }
  2814. }
  2815.  
  2816.  
  2817.  
  2818. /* tvtpos --- position cursor on Allen's TV Typetwriter II */
  2819.  
  2820. static tvtpos (row, col)
  2821. int row, col;
  2822. {
  2823.     register int horirel, horiabs, vertrel, vertabs;
  2824.  
  2825.     horirel = col - Curcol;
  2826.     if (horirel < 0)
  2827.         horirel = -horirel;
  2828.  
  2829.     horiabs = col;
  2830.  
  2831.     if (row <= Currow)
  2832.         vertrel = Currow - row;
  2833.     else
  2834.         vertrel = Nrows - (row - Currow);
  2835.  
  2836.     if (row == 0)
  2837.         vertabs = 0;
  2838.     else
  2839.         vertabs = Nrows - row;
  2840.  
  2841.     if (1 + horiabs + vertabs <= horirel + vertrel)
  2842.     {
  2843.         twrite (1, "\014", 1);
  2844.         Currow = Curcol = 0;
  2845.     }
  2846.  
  2847.     while (Currow != row)
  2848.     {
  2849.         twrite (1, "\013", 1);
  2850.         Currow--;
  2851.         if (Currow < 0)
  2852.             Currow = Nrows - 1;
  2853.     }
  2854.  
  2855.     if (Curcol > col)
  2856.         for (; Curcol != col; Curcol--)
  2857.             twrite (1, "\b", 1);
  2858.     else
  2859.         for (; Curcol != col; Curcol++)
  2860.             twrite (1, "\t", 1);
  2861. }
  2862.  
  2863.  
  2864.  
  2865. /* regentpos --- position cursor on ADDS Regent 100 */
  2866.  
  2867. static regentpos (row, col)
  2868. int row, col;
  2869. {
  2870.     int dist;
  2871.     char coord;
  2872.  
  2873.     dist = col - Curcol;
  2874.     if (dist < 0)
  2875.         dist = -dist;
  2876.     
  2877.     if (dist > 4 || Currow != row)
  2878.     {
  2879.         twrite (1, "\033Y", 2);
  2880.         coord = ' ' + row;
  2881.         twrite (1, &coord, 1);
  2882.         coord = ' ' + col;
  2883.         twrite (1, &coord, 1);
  2884.         Currow = row;
  2885.         Curcol = col;
  2886.     }
  2887.     else
  2888.     {
  2889.         while (row < Currow)
  2890.         {
  2891.             twrite (1, "\032", 1);    /* SUB, cursor up */
  2892.             Currow--;
  2893.         }
  2894.         while (row > Currow)
  2895.         {
  2896.             twrite (1, "\n", 1);
  2897.             Currow++;
  2898.             Curcol = 1;
  2899.         }
  2900.         if (col > Curcol)
  2901.             while (col != Curcol)
  2902.             {
  2903.                 twrite (1, &Screen_image[Currow][Curcol], 1);
  2904.                 Curcol++;
  2905.             }
  2906.         else if ((Curcol - col) * 2 >= Ncols)
  2907.             while (col != Curcol)
  2908.             {
  2909.                 twrite (1, "\006", 1);    /* ACK, cursor right */
  2910.                 if (Curcol == Ncols)
  2911.                     Curcol = 1;
  2912.                 else
  2913.                     Curcol++;
  2914.             }
  2915.         else
  2916.             while (col != Curcol)
  2917.             {
  2918.                 twrite (1, "\b", 1);
  2919.                 Curcol--;
  2920.             }
  2921.     }
  2922. }
  2923.  
  2924.  
  2925.  
  2926. /* vipos --- position cursor on Visual 200 & 50 */
  2927.  
  2928. static vipos (row, col)
  2929. register int row, col;
  2930. {
  2931.     register int dist;
  2932.     register char coord;
  2933.  
  2934.     if (row == Currow + 1 && col < 3)
  2935.     {
  2936.         twrite (1, "\015\012", 2);
  2937.         Currow++;
  2938.         Curcol = 0;
  2939.     }
  2940.     dist = col - Curcol;
  2941.     if (Term_type == VI200 && row == Currow && col < 72 && dist > 2
  2942.         && dist < 8 && (col + 1) % 8 < 2)
  2943.     {
  2944.         twrite (1, "\t", 1);
  2945.         Curcol = ((Curcol + 7) / 8) * 8;
  2946.         dist = col - Curcol;
  2947.     }
  2948.     if (dist < 0)
  2949.         dist = -dist;
  2950.     if (row == Currow && dist < 4)  /* 4 chars for abs. position */
  2951.     {
  2952.         while (Curcol < col)
  2953.         {
  2954.             twrite (1, &Screen_image[Currow][Curcol], 1);
  2955.             Curcol++;
  2956.         }
  2957.         while (Curcol > col)
  2958.         {
  2959.             twrite (1, "\b", 1);
  2960.             Curcol--;
  2961.         }
  2962.     }
  2963.     else
  2964.     {
  2965.         twrite (1, "\033Y", 2);
  2966.         coord = row + ' ';
  2967.         twrite (1, &coord, 1);
  2968.         coord = col + ' ';
  2969.         twrite (1, &coord, 1);
  2970.         Currow = row;
  2971.         Curcol = col;
  2972.     }
  2973. }
  2974.  
  2975.  
  2976.  
  2977. /* vcpos --- position cursor Volker-Craig 4404 (ADM3A mode) */
  2978.  
  2979. static vcpos (row, col)
  2980. int row, col;
  2981. {
  2982.     int dist;
  2983.     char coord;
  2984.  
  2985.     dist = col - Curcol;
  2986.     if (dist < 0)
  2987.         dist = -dist;
  2988.     if (row == Currow && dist < 4)  /* 4 chars for abs. position */
  2989.     {
  2990.         while (Curcol < col)
  2991.         {
  2992.             twrite (1, &Screen_image[Currow][Curcol], 1);
  2993.             Curcol++;
  2994.         }
  2995.         while (Curcol > col)
  2996.         {
  2997.             twrite (1, "\b", 1);
  2998.             Curcol--;
  2999.         }
  3000.     }
  3001.     else
  3002.     {
  3003.         twrite (1, "\033=", 2);
  3004.         coord = row + ' ';
  3005.         twrite (1, &coord, 1);
  3006.         coord = col + ' ';
  3007.         twrite (1, &coord, 1);
  3008.         Currow = row;
  3009.         Curcol = col;
  3010.     }
  3011. }
  3012.  
  3013.  
  3014. /* espritpos --- position cursor on Hazeltine Esprit */
  3015.  
  3016. static espritpos (row, col)
  3017. int row, col;
  3018. {
  3019.     int dist;
  3020.     char c;
  3021.  
  3022.     dist = col - Curcol;
  3023.     if (dist < 0)
  3024.         dist = -dist;
  3025.     if (row == Currow && dist < 4)  /* 4 chars for abs. position */
  3026.     {
  3027.         while (Curcol < col)
  3028.         {
  3029.             twrite (1, &Screen_image[Currow][Curcol], 1);
  3030.             Curcol++;
  3031.         }
  3032.         while (Curcol > col)
  3033.         {
  3034.             twrite (1, "\b", 1);
  3035.             Curcol--;
  3036.         }
  3037.     }
  3038.     else
  3039.     {
  3040.         twrite (1, "\033\021", 2);
  3041.         c = col >= 32 ? col : col + '`';
  3042.         twrite (1, &c, 1);
  3043.         c = row >= 32 ? row : row + '`';
  3044.         twrite (1, &c, 1);
  3045.         Currow = row;
  3046.         Curcol = col;
  3047.     }
  3048. }
  3049.  
  3050. /* uhcm --- universal horizontal cursor motion */
  3051.  
  3052. static uhcm (col)
  3053. int col;
  3054. {
  3055.     while (Curcol < col)
  3056.     {
  3057.         twrite (1, &Screen_image[Currow][Curcol], 1);
  3058.         Curcol++;
  3059.     }
  3060.  
  3061.     while (Curcol > col)
  3062.     {
  3063.         twrite (1, "\b", 1);
  3064.         Curcol--;
  3065.     }
  3066. }
  3067. #endif
  3068. SHAR_EOF
  3069. fi
  3070. exit 0
  3071. #    End of shell archive
  3072.  
  3073.